##// END OF EJS Templates
Fixed integrated build on OSX
Fixed integrated build on OSX

File last commit:

r716:e7d88adcf7ee
r721:a5d0004908a0
Show More
qlegend.cpp
661 lines | 20.9 KiB | text/x-c | CppLexer
sauimone
framework for legend
r524 #include "qchartglobal.h"
#include "qlegend.h"
#include "qseries.h"
sauimone
Separated legend marker to private header. Added signals for left and right mouse click
r547 #include "legendmarker_p.h"
sauimone
Scrolling logic to legend
r716 #include "legendscrollbutton_p.h"
sauimone
more intelligent legend. fixed compiler warning in bar.cpp
r565 #include "qxyseries.h"
#include "qlineseries.h"
#include "qareaseries.h"
#include "qscatterseries.h"
#include "qsplineseries.h"
#include "qbarseries.h"
#include "qstackedbarseries.h"
#include "qpercentbarseries.h"
#include "qbarset.h"
#include "qpieseries.h"
#include "qpieslice.h"
sauimone
Adaptive layout to legend. Tries to fit all items inside given maximum size
r626 #include "chartpresenter_p.h"
sauimone
First version of legend. Simple markers and serie names. Using drilldown as example for now.
r529 #include <QPainter>
#include <QPen>
sauimone
framework for legend
r524
sauimone
Separated legend marker to private header. Added signals for left and right mouse click
r547 #include <QGraphicsSceneEvent>
sauimone
First version of legend. Simple markers and serie names. Using drilldown as example for now.
r529
sauimone
Separated legend marker to private header. Added signals for left and right mouse click
r547 QTCOMMERCIALCHART_BEGIN_NAMESPACE
sauimone
First version of legend. Simple markers and serie names. Using drilldown as example for now.
r529
sauimone
framework for legend
r524 QLegend::QLegend(QGraphicsItem *parent)
: QGraphicsObject(parent)
sauimone
Adaptive layout to legend. Tries to fit all items inside given maximum size
r626 ,mPos(0,0)
,mSize(0,0)
sauimone
legend scaling with chart
r582 ,mMinimumSize(50,20) // TODO: magic numbers
sauimone
legend layouting change
r616 ,mMaximumSize(150,100)
sauimone
Scrolling logic to legend
r716 ,m_brush(Qt::darkGray) // TODO: from theme?
,mPreferredLayout(QLegend::PreferredLayoutTop)
,mFirstMarker(0)
,mMargin(5)
sauimone
framework for legend
r524 {
sauimone
Scrolling logic to legend
r716 // setVisible(false);
mScrollButtonLeft = new LegendScrollButton(LegendScrollButton::ScrollButtonIdLeft, this);
mScrollButtonRight = new LegendScrollButton(LegendScrollButton::ScrollButtonIdRight, this);
mScrollButtonUp = new LegendScrollButton(LegendScrollButton::ScrollButtonIdUp, this);
mScrollButtonDown = new LegendScrollButton(LegendScrollButton::ScrollButtonIdDown, this);
connect(mScrollButtonLeft,SIGNAL(clicked(QGraphicsSceneMouseEvent*)),this,SLOT(handleScrollButtonClicked(QGraphicsSceneMouseEvent*)));
connect(mScrollButtonRight,SIGNAL(clicked(QGraphicsSceneMouseEvent*)),this,SLOT(handleScrollButtonClicked(QGraphicsSceneMouseEvent*)));
connect(mScrollButtonUp,SIGNAL(clicked(QGraphicsSceneMouseEvent*)),this,SLOT(handleScrollButtonClicked(QGraphicsSceneMouseEvent*)));
connect(mScrollButtonDown,SIGNAL(clicked(QGraphicsSceneMouseEvent*)),this,SLOT(handleScrollButtonClicked(QGraphicsSceneMouseEvent*)));
sauimone
Adaptive layout to legend. Tries to fit all items inside given maximum size
r626 setZValue(ChartPresenter::LegendZValue);
sauimone
framework for legend
r524 }
void QLegend::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
Tero Ahola
Squashed bunch of warnings
r611 Q_UNUSED(option)
Q_UNUSED(widget)
sauimone
Scrolling logic to legend
r716 painter->setOpacity(0.8);
Michal Klocek
Adds force option to chartTheme...
r645 painter->setPen(m_pen);
painter->setBrush(m_brush);
sauimone
Adaptive layout to legend. Tries to fit all items inside given maximum size
r626 painter->drawRect(boundingRect());
sauimone
framework for legend
r524 }
QRectF QLegend::boundingRect() const
{
sauimone
Adaptive layout to legend. Tries to fit all items inside given maximum size
r626 return QRectF(mPos,mSize);
sauimone
framework for legend
r524 }
Michal Klocek
Adds force option to chartTheme...
r645 void QLegend::setBrush(const QBrush& brush)
sauimone
background to legend, theme applies
r540 {
Michal Klocek
Adds force option to chartTheme...
r645 if(m_brush!=brush){
m_brush = brush;
update();
}
}
QBrush QLegend::brush() const
{
return m_brush;
}
void QLegend::setPen(const QPen& pen)
{
if(m_pen!=pen){
m_pen = pen;
update();
}
sauimone
background to legend, theme applies
r540 }
Michal Klocek
Adds force option to chartTheme...
r645 QPen QLegend::pen() const
sauimone
background to legend, theme applies
r540 {
Michal Klocek
Adds force option to chartTheme...
r645 return m_pen;
sauimone
background to legend, theme applies
r540 }
sauimone
legend layouting change
r616 void QLegend::setPreferredLayout(QLegend::PreferredLayout preferred)
{
mPreferredLayout = preferred;
sauimone
Scrolling logic to legend
r716 updateLayout();
}
QLegend::PreferredLayout QLegend::preferredLayout() const
{
return mPreferredLayout;
sauimone
legend layouting change
r616 }
sauimone
Adaptive layout to legend. Tries to fit all items inside given maximum size
r626 QSizeF QLegend::maximumSize() const
sauimone
legend scaling with chart
r582 {
sauimone
Adaptive layout to legend. Tries to fit all items inside given maximum size
r626 return mMaximumSize;
sauimone
legend scaling with chart
r582 }
sauimone
Adaptive layout to legend. Tries to fit all items inside given maximum size
r626 void QLegend::setMaximumSize(const QSizeF size)
sauimone
legend scaling with chart
r582 {
sauimone
Adaptive layout to legend. Tries to fit all items inside given maximum size
r626 mMaximumSize = size;
sauimone
Scrolling logic to legend
r716 updateLayout();
sauimone
Adaptive layout to legend. Tries to fit all items inside given maximum size
r626 }
void QLegend::setSize(const QSizeF size)
{
mSize = size;
if (mSize.width() > mMaximumSize.width()) {
mSize.setWidth(mMaximumSize.width());
}
if (mSize.height() > mMaximumSize.height()) {
mSize.setHeight(mMaximumSize.height());
}
}
void QLegend::setPos(const QPointF &pos)
{
mPos = pos;
sauimone
Scrolling logic to legend
r716 updateLayout();
sauimone
legend scaling with chart
r582 }
Tero Ahola
Squashed bunch of warnings
r611 void QLegend::handleSeriesAdded(QSeries* series, Domain* domain)
sauimone
framework for legend
r524 {
Tero Ahola
Squashed bunch of warnings
r611 Q_UNUSED(domain)
sauimone
handleThemeChanged slot to legend.
r586 createMarkers(series);
sauimone
Added handling for pieslice add/remove to legend
r637 connectSeries(series);
sauimone
Scrolling logic to legend
r716 updateLayout();
sauimone
handleThemeChanged slot to legend.
r586 }
void QLegend::handleSeriesRemoved(QSeries* series)
{
sauimone
Added handling for pieslice add/remove to legend
r637 disconnectSeries(series);
sauimone
handleThemeChanged slot to legend.
r586 if (series->type() == QSeries::SeriesTypeArea)
{
// This is special case. Area series has upper and lower series, which each have markers
QAreaSeries* s = static_cast<QAreaSeries*> (series);
deleteMarkers(s->upperSeries());
deleteMarkers(s->lowerSeries());
} else {
deleteMarkers(series);
}
sauimone
Scrolling logic to legend
r716 updateLayout();
sauimone
handleThemeChanged slot to legend.
r586 }
sauimone
Added handling for pieslice add/remove to legend
r637 void QLegend::handleAdded(QList<QPieSlice*> slices)
{
QPieSeries* series = static_cast<QPieSeries*> (sender());
foreach(QPieSlice* s, slices) {
LegendMarker* marker = new LegendMarker(series,s,this);
marker->setName(s->label());
marker->setBrush(s->sliceBrush());
connect(marker,SIGNAL(clicked(QPieSlice*,Qt::MouseButton)),this,SIGNAL(clicked(QPieSlice*,Qt::MouseButton)));
connect(s,SIGNAL(changed()),marker,SLOT(changed()));
connect(s,SIGNAL(destroyed()),marker,SLOT(deleteLater()));
sauimone
fixed bug in legend marker removing
r643 connect(marker,SIGNAL(destroyed()),this,SLOT(handleMarkerDestroyed()));
sauimone
Added handling for pieslice add/remove to legend
r637 mMarkers.append(marker);
childItems().append(marker);
}
sauimone
Scrolling logic to legend
r716 updateLayout();
sauimone
Added handling for pieslice add/remove to legend
r637 }
sauimone
fixed bug in legend marker removing
r643 void QLegend::handleRemoved(QList<QPieSlice *> slices)
{
Tero Ahola
Warnings treated as errors; fixed one
r647 Q_UNUSED(slices)
sauimone
fixed bug in legend marker removing
r643 // Propably no need to listen for this, since removed slices are deleted and we listen destroyed signal
// qDebug() << "QLegend::handleRemoved(QList<QPieSlice*> slices) count:" << slices.count();
}
sauimone
Added handling for pieslice add/remove to legend
r637 void QLegend::handleMarkerDestroyed()
{
// TODO: what if more than one markers are destroyed and we update layout after first one?
LegendMarker* m = static_cast<LegendMarker*> (sender());
mMarkers.removeOne(m);
sauimone
Scrolling logic to legend
r716 updateLayout();
}
void QLegend::handleScrollButtonClicked(QGraphicsSceneMouseEvent *event)
{
Q_UNUSED(event); // Maybe later somethin happens with right click...
// TODO: detect sender object. scroll to appropiate direction.
LegendScrollButton* scrollButton = static_cast<LegendScrollButton*> (sender());
Q_ASSERT(scrollButton);
switch (scrollButton->id()) {
case LegendScrollButton::ScrollButtonIdLeft:
case LegendScrollButton::ScrollButtonIdUp: {
// Lower limit is same in these cases
mFirstMarker--;
checkMarkerBounds();
break;
}
case LegendScrollButton::ScrollButtonIdRight:
case LegendScrollButton::ScrollButtonIdDown: {
mFirstMarker++;
checkMarkerBounds();
break;
}
default: {
break;
}
}
updateLayout();
sauimone
Added handling for pieslice add/remove to legend
r637 }
void QLegend::connectSeries(QSeries *series)
{
// Connect relevant signals from series
switch (series->type())
{
case QSeries::SeriesTypeLine: {
// QLineSeries* lineSeries = static_cast<QLineSeries*>(series);
break;
}
case QSeries::SeriesTypeArea: {
// QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
break;
}
case QSeries::SeriesTypeBar: {
// QBarSeries* barSeries = static_cast<QBarSeries*>(series);
break;
}
case QSeries::SeriesTypeStackedBar: {
// QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
break;
}
case QSeries::SeriesTypePercentBar: {
// QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
break;
}
case QSeries::SeriesTypeScatter: {
// QScatterSeries *scatterSeries = static_cast<QScatterSeries *>(series);
break;
}
case QSeries::SeriesTypePie: {
QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
connect(pieSeries,SIGNAL(added(QList<QPieSlice*>)),this,SLOT(handleAdded(QList<QPieSlice*>)));
// connect(pieSeries,SIGNAL(removed(QList<QPieSlice*>)),this,SLOT(handleRemoved(QList<QPieSlice*>)));
break;
}
case QSeries::SeriesTypeSpline: {
// QSplineSeries* splineSeries = static_cast<QSplineSeries*>(series);
break;
}
default: {
qDebug()<< "QLegend::connectSeries" << series->type() << "not implemented.";
break;
}
}
}
void QLegend::disconnectSeries(QSeries *series)
{
// Connect relevant signals from series
switch (series->type())
{
case QSeries::SeriesTypeLine: {
// QLineSeries* lineSeries = static_cast<QLineSeries*>(series);
break;
}
case QSeries::SeriesTypeArea: {
// QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
break;
}
case QSeries::SeriesTypeBar: {
// QBarSeries* barSeries = static_cast<QBarSeries*>(series);
break;
}
case QSeries::SeriesTypeStackedBar: {
// QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
break;
}
case QSeries::SeriesTypePercentBar: {
// QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
break;
}
case QSeries::SeriesTypeScatter: {
// QScatterSeries *scatterSeries = static_cast<QScatterSeries *>(series);
break;
}
case QSeries::SeriesTypePie: {
QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
disconnect(pieSeries,SIGNAL(added(QList<QPieSlice*>)),this,SLOT(handleAdded(QList<QPieSlice*>)));
// disconnect(pieSeries,SIGNAL(removed(QList<QPieSlice*>)),this,SLOT(handleRemoved(QList<QPieSlice*>)));
break;
}
case QSeries::SeriesTypeSpline: {
// QSplineSeries* splineSeries = static_cast<QSplineSeries*>(series);
break;
}
default: {
qDebug()<< "QLegend::disconnectSeries" << series->type() << "not implemented.";
break;
}
}
}
sauimone
handleThemeChanged slot to legend.
r586 void QLegend::createMarkers(QSeries *series)
{
sauimone
more intelligent legend. fixed compiler warning in bar.cpp
r565 switch (series->type())
{
case QSeries::SeriesTypeLine: {
QLineSeries* lineSeries = static_cast<QLineSeries*>(series);
sauimone
handleThemeChanged slot to legend.
r586 appendMarkers(lineSeries);
sauimone
more intelligent legend. fixed compiler warning in bar.cpp
r565 break;
}
case QSeries::SeriesTypeArea: {
QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
sauimone
handleThemeChanged slot to legend.
r586 appendMarkers(areaSeries->upperSeries());
Michal Klocek
Bugfix dangling pointer in qlegend, remove debug info
r572 if(areaSeries->lowerSeries())
sauimone
handleThemeChanged slot to legend.
r586 appendMarkers(areaSeries->lowerSeries());
sauimone
more intelligent legend. fixed compiler warning in bar.cpp
r565 break;
}
case QSeries::SeriesTypeBar: {
QBarSeries* barSeries = static_cast<QBarSeries*>(series);
sauimone
handleThemeChanged slot to legend.
r586 appendMarkers(barSeries);
sauimone
more intelligent legend. fixed compiler warning in bar.cpp
r565 break;
}
case QSeries::SeriesTypeStackedBar: {
QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
sauimone
handleThemeChanged slot to legend.
r586 appendMarkers(stackedBarSeries);
sauimone
more intelligent legend. fixed compiler warning in bar.cpp
r565 break;
}
case QSeries::SeriesTypePercentBar: {
QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
sauimone
handleThemeChanged slot to legend.
r586 appendMarkers(percentBarSeries);
sauimone
more intelligent legend. fixed compiler warning in bar.cpp
r565 break;
}
case QSeries::SeriesTypeScatter: {
QScatterSeries *scatterSeries = static_cast<QScatterSeries *>(series);
sauimone
handleThemeChanged slot to legend.
r586 appendMarkers(scatterSeries);
sauimone
more intelligent legend. fixed compiler warning in bar.cpp
r565 break;
}
case QSeries::SeriesTypePie: {
QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
sauimone
handleThemeChanged slot to legend.
r586 appendMarkers(pieSeries);
sauimone
more intelligent legend. fixed compiler warning in bar.cpp
r565 break;
}
case QSeries::SeriesTypeSpline: {
QSplineSeries* splineSeries = static_cast<QSplineSeries*>(series);
sauimone
handleThemeChanged slot to legend.
r586 appendMarkers(splineSeries);
sauimone
more intelligent legend. fixed compiler warning in bar.cpp
r565 break;
}
default: {
sauimone
handleThemeChanged slot to legend.
r586 qDebug()<< "QLegend::createMarkers" << series->type() << "not implemented.";
sauimone
more intelligent legend. fixed compiler warning in bar.cpp
r565 break;
}
}
sauimone
Legend can handle removing of series
r576 }
sauimone
handleThemeChanged slot to legend.
r586 void QLegend::appendMarkers(QXYSeries* series)
sauimone
First version of legend. Simple markers and serie names. Using drilldown as example for now.
r529 {
sauimone
more intelligent legend. fixed compiler warning in bar.cpp
r565 LegendMarker* marker = new LegendMarker(series,this);
marker->setName(series->name());
marker->setBrush(series->brush());
sauimone
combined clicked and rightclicked events of legend to one event with parameter
r567 connect(marker,SIGNAL(clicked(QSeries*,Qt::MouseButton)),this,SIGNAL(clicked(QSeries*,Qt::MouseButton)));
sauimone
Added handling for pieslice add/remove to legend
r637 connect(marker,SIGNAL(destroyed()),this,SLOT(handleMarkerDestroyed()));
sauimone
more intelligent legend. fixed compiler warning in bar.cpp
r565 mMarkers.append(marker);
childItems().append(marker);
}
sauimone
handleThemeChanged slot to legend.
r586 void QLegend::appendMarkers(QBarSeries *series)
sauimone
more intelligent legend. fixed compiler warning in bar.cpp
r565 {
foreach(QBarSet* s, series->barSets()) {
sauimone
Legend can handle removing of series
r576 LegendMarker* marker = new LegendMarker(series,s,this);
sauimone
more intelligent legend. fixed compiler warning in bar.cpp
r565 marker->setName(s->name());
marker->setBrush(s->brush());
sauimone
combined clicked and rightclicked events of legend to one event with parameter
r567 connect(marker,SIGNAL(clicked(QBarSet*,Qt::MouseButton)),this,SIGNAL(clicked(QBarSet*,Qt::MouseButton)));
sauimone
fixed changed singal name in legend
r670 connect(s,SIGNAL(valueChanged()),marker,SLOT(changed()));
sauimone
Added handling for pieslice add/remove to legend
r637 connect(marker,SIGNAL(destroyed()),this,SLOT(handleMarkerDestroyed()));
sauimone
more intelligent legend. fixed compiler warning in bar.cpp
r565 mMarkers.append(marker);
childItems().append(marker);
sauimone
First version of legend. Simple markers and serie names. Using drilldown as example for now.
r529 }
sauimone
more intelligent legend. fixed compiler warning in bar.cpp
r565 }
sauimone
First version of legend. Simple markers and serie names. Using drilldown as example for now.
r529
sauimone
handleThemeChanged slot to legend.
r586 void QLegend::appendMarkers(QPieSeries *series)
sauimone
more intelligent legend. fixed compiler warning in bar.cpp
r565 {
foreach(QPieSlice* s, series->slices()) {
sauimone
Legend can handle removing of series
r576 LegendMarker* marker = new LegendMarker(series,s,this);
sauimone
more intelligent legend. fixed compiler warning in bar.cpp
r565 marker->setName(s->label());
marker->setBrush(s->sliceBrush());
sauimone
combined clicked and rightclicked events of legend to one event with parameter
r567 connect(marker,SIGNAL(clicked(QPieSlice*,Qt::MouseButton)),this,SIGNAL(clicked(QPieSlice*,Qt::MouseButton)));
sauimone
removed handlethemechange for legend. Too complex solution. Legend now listens the changed signals from series
r587 connect(s,SIGNAL(changed()),marker,SLOT(changed()));
sauimone
Added handling for pieslice add/remove to legend
r637 connect(s,SIGNAL(destroyed()),marker,SLOT(deleteLater()));
connect(marker,SIGNAL(destroyed()),this,SLOT(handleMarkerDestroyed()));
sauimone
more intelligent legend. fixed compiler warning in bar.cpp
r565 mMarkers.append(marker);
childItems().append(marker);
sauimone
First version of legend. Simple markers and serie names. Using drilldown as example for now.
r529 }
}
sauimone
handleThemeChanged slot to legend.
r586 void QLegend::deleteMarkers(QSeries *series)
{
// Search all markers that belong to given series and delete them.
foreach (LegendMarker *m, mMarkers) {
if (m->series() == series) {
mMarkers.removeOne(m);
delete m;
}
}
}
sauimone
Scrolling logic to legend
r716 void QLegend::updateLayout()
sauimone
First version of legend. Simple markers and serie names. Using drilldown as example for now.
r529 {
// Calculate layout for markers and text
if (mMarkers.count() <= 0) {
// Nothing to do
return;
}
sauimone
Scrolling logic to legend
r716 checkMarkerBounds();
sauimone
First version of legend. Simple markers and serie names. Using drilldown as example for now.
r529
sauimone
Adaptive layout to legend. Tries to fit all items inside given maximum size
r626 // Find out widest item.
sauimone
Scrolling logic to legend
r716 QSizeF markerMaxSize = maximumMarkerSize();
sauimone
Adaptive layout to legend. Tries to fit all items inside given maximum size
r626
sauimone
Scrolling logic to legend
r716 // Use max height as scroll button size
rescaleScrollButtons(QSize(markerMaxSize.height() ,markerMaxSize.height()));
sauimone
legend layouting change
r616
sauimone
Adaptive layout to legend. Tries to fit all items inside given maximum size
r626 qreal totalWidth = 0;
qreal totalHeight = 0;
sauimone
legend layouting change
r616 switch (mPreferredLayout)
{
sauimone
Scrolling logic to legend
r716 // Both cases organise items horizontally
case QLegend::PreferredLayoutBottom:
case QLegend::PreferredLayoutTop: {
qreal xStep = markerMaxSize.width();
qreal x = mPos.x() + mMargin;
qreal y = mPos.y() + mMargin;
sauimone
Adaptive layout to legend. Tries to fit all items inside given maximum size
r626 int column = 0;
int maxColumns = 1;
sauimone
Scrolling logic to legend
r716 qreal scrollButtonPadding = 0;
// Set correct visibility for scroll scrollbuttons
if (scrollButtonsVisible()) {
mScrollButtonLeft->setVisible(true);
mScrollButtonRight->setVisible(true);
totalWidth += (mScrollButtonLeft->boundingRect().width() + mMargin) * 2; // scrollbuttons visible, so add their width to total width
x += mScrollButtonLeft->boundingRect().width() + mMargin; // start position changes by scrollbutton width
scrollButtonPadding = mScrollButtonLeft->boundingRect().width();
} else {
mScrollButtonLeft->setVisible(false);
mScrollButtonRight->setVisible(false);
}
mScrollButtonUp->setVisible(false);
mScrollButtonDown->setVisible(false);
for (int i=0; i<mMarkers.count(); i++) {
LegendMarker* m = mMarkers.at(i);
if (i<mFirstMarker) {
// Markers before first are not visible.
m->setVisible(false);
} else {
if ((x + xStep + scrollButtonPadding) > (mPos.x() + mMaximumSize.width())) {
// This marker would go outside legend rect.
m->setVisible(false);
} else {
// This marker is ok
m->setVisible(true);
m->setPos(x,y);
x += xStep;
column++;
}
sauimone
Adaptive layout to legend. Tries to fit all items inside given maximum size
r626 }
sauimone
Scrolling logic to legend
r716 maxColumns = column;
sauimone
legend layouting change
r616 }
sauimone
Scrolling logic to legend
r716
mScrollButtonLeft->setPos(mPos.x() + mMargin, y);
mScrollButtonRight->setPos(x+mMargin,y);
totalWidth += maxColumns * markerMaxSize.width() + mMargin * 2;
totalHeight = markerMaxSize.height() + mMargin * 2;
sauimone
legend layouting change
r616 break;
sauimone
First version of legend. Simple markers and serie names. Using drilldown as example for now.
r529 }
sauimone
Scrolling logic to legend
r716 // Both cases organize items vertically
case QLegend::PreferredLayoutLeft:
case QLegend::PreferredLayoutRight: {
qreal yStep = markerMaxSize.height();
qreal x = mPos.x() + mMargin;
qreal y = mPos.y() + mMargin;
int row = 1;
int maxRows = 1;
qreal scrollButtonPadding = 0;
// Set correct visibility for scroll scrollbuttons
if (scrollButtonsVisible()) {
mScrollButtonUp->setVisible(true);
mScrollButtonDown->setVisible(true);
totalHeight += (mScrollButtonUp->boundingRect().height() + mMargin) * 2; // scrollbuttons visible, so add their height to total height
y += mScrollButtonUp->boundingRect().height() + mMargin; // start position changes by scrollbutton height
scrollButtonPadding = mScrollButtonUp->boundingRect().height();
} else {
mScrollButtonUp->setVisible(false);
mScrollButtonDown->setVisible(false);
sauimone
legend layouting change
r616 }
sauimone
Scrolling logic to legend
r716 mScrollButtonLeft->setVisible(false);
mScrollButtonRight->setVisible(false);
for (int i=0; i<mMarkers.count(); i++) {
LegendMarker* m = mMarkers.at(i);
if (i<mFirstMarker) {
// Markers before first are not visible.
m->setVisible(false);
} else {
if ((y + yStep + scrollButtonPadding) > (mPos.y() + mMaximumSize.height())) {
// This marker would go outside legend rect.
m->setVisible(false);
} else {
// This marker is ok
m->setVisible(true);
m->setPos(x,y);
y += yStep;
row++;
}
}
maxRows = row;
}
mScrollButtonUp->setPos(mPos.x() + mMargin, mPos.y() + mMargin);
mScrollButtonDown->setPos(mPos.x() + mMargin, y + mMargin);
totalWidth += markerMaxSize.width() + mMargin * 2;
totalHeight = maxRows * markerMaxSize.height() + mMargin * 4 + scrollButtonPadding; // TODO: check this
/*
qreal yStep = markerMaxSize.height();
qreal x = mPos.x() + mMargin;
qreal y = mPos.y() + mMargin;
sauimone
Adaptive layout to legend. Tries to fit all items inside given maximum size
r626 int row = 0;
int maxRows = 1;
int maxColumns = 1;
sauimone
Scrolling logic to legend
r716 for (int i=0; i<mMarkers.count(); i++) {
LegendMarker* m = mMarkers.at(i);
if (i<mFirstMarker) {
// Markers before first are not visible.
m->setVisible(false);
} else {
if ((y + markerMaxSize.height() + mMargin*2) > (mPos.y() + mMaximumSize.height())) {
// This marker would go outside legend rect.
m->setVisible(false);
} else {
// This marker is ok
m->setVisible(true);
maxRows = row;
m->setPos(x,y);
y += yStep;
row++;
}
sauimone
Adaptive layout to legend. Tries to fit all items inside given maximum size
r626 }
sauimone
Scrolling logic to legend
r716 maxRows = row;
sauimone
legend layouting change
r616 }
sauimone
Scrolling logic to legend
r716 totalWidth = maxColumns * markerMaxSize.width() + mMargin * 2;
totalHeight = maxRows * markerMaxSize.height() + mMargin * 2;
*/
sauimone
legend layouting change
r616 break;
}
default: {
break;
}
}
sauimone
Adaptive layout to legend. Tries to fit all items inside given maximum size
r626 mSize.setWidth(totalWidth);
mSize.setHeight(totalHeight);
sauimone
Scrolling logic to legend
r716
update();
}
void QLegend::rescaleScrollButtons(const QSize &size)
{
QPolygonF left;
left << QPointF(size.width(),0) << QPointF(0,size.height()/2) << QPointF(size.width(),size.height());
QPolygonF right;
right << QPointF(0,0) << QPointF(size.width(),size.height()/2) << QPointF(0,size.height());
QPolygonF up;
up << QPointF(0,size.height()) << QPointF(size.width()/2,0) << QPointF(size.width(),size.height());
QPolygonF down;
down << QPointF(0,0) << QPointF(size.width()/2,size.height()) << QPointF(size.width(),0);
mScrollButtonLeft->setPolygon(left);
mScrollButtonRight->setPolygon(right);
mScrollButtonUp->setPolygon(up);
mScrollButtonDown->setPolygon(down);
}
QSizeF QLegend::maximumMarkerSize()
{
QSizeF max(0,0);
foreach (LegendMarker* m, mMarkers) {
if (m->boundingRect().width() > max.width()) {
max.setWidth(m->boundingRect().width());
}
if (m->boundingRect().height() > max.height()) {
max.setHeight(m->boundingRect().height());
}
}
return max;
}
void QLegend::checkMarkerBounds()
{
if ((mPreferredLayout == QLegend::PreferredLayoutLeft) || (mPreferredLayout == QLegend::PreferredLayoutRight)) {
// Bounds limited by height
int max;
if (scrollButtonsVisible()) {
max = (mMaximumSize.height() - mScrollButtonLeft->boundingRect().height() * 2 - mMargin*2) / maximumMarkerSize().height();
} else {
max = mMaximumSize.height() / maximumMarkerSize().height();
}
if (mFirstMarker > mMarkers.count() - max) {
mFirstMarker = mMarkers.count() - max;
}
} else {
// Bounds limited by width
int max;
if (scrollButtonsVisible()) {
max = (mMaximumSize.width() - mScrollButtonLeft->boundingRect().width() * 2 - mMargin*2) / maximumMarkerSize().width();
} else {
max = mMaximumSize.width() / maximumMarkerSize().width();
}
if (mFirstMarker > mMarkers.count() - max) {
mFirstMarker = mMarkers.count() - max;
}
}
if (mFirstMarker < 0) {
mFirstMarker = 0;
}
}
bool QLegend::scrollButtonsVisible()
{
// Just a helper to clarify, what the magic below means :)
if ((mPreferredLayout == QLegend::PreferredLayoutTop) || (mPreferredLayout == QLegend::PreferredLayoutBottom)) {
return (maximumMarkerSize().width() * mMarkers.count() + mMargin * 3 > mMaximumSize.width());
}
return (maximumMarkerSize().height() * mMarkers.count() + mMargin * 3 > mMaximumSize.height());
sauimone
First version of legend. Simple markers and serie names. Using drilldown as example for now.
r529 }
sauimone
framework for legend
r524 #include "moc_qlegend.cpp"
QTCOMMERCIALCHART_END_NAMESPACE