##// END OF EJS Templates
Fix axis geometry when there is no axis title...
Fix axis geometry when there is no axis title SizeHint won't include title padding when there is no title, yet updateGeometry() always assumed it was there when determining space for labels, causing truncated labels when title was missing. Also made missing/empty/hidden axis title work consistently. Now axis geometries should be updated correctly always when title text or visibility status changes. Task-number: QTRD-1903 Reviewed-by: Mika Salmela

File last commit:

r2411:6fca0e6f42a3
r2415:65ea14fdb747
Show More
chartlayout.cpp
394 lines | 12.9 KiB | text/x-c | CppLexer
Michal Klocek
Adds missing license headers
r1535 /****************************************************************************
**
** Copyright (C) 2012 Digia Plc
** All rights reserved.
** For any questions to Digia, please use contact form at http://qt.digia.com
**
** This file is part of the Qt Commercial Charts Add-on.
**
** $QT_BEGIN_LICENSE$
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.
**
** If you have questions regarding the use of this file, please use
** contact form at http://qt.digia.com
** $QT_END_LICENSE$
**
****************************************************************************/
Michal Klocek
Refactors layout managment...
r1534 #include "chartlayout_p.h"
#include "chartpresenter_p.h"
Michal Klocek
Bugfixes for layout...
r1837 #include "qlegend_p.h"
Michal Klocek
Refactors layout managment...
r1534 #include "chartaxis_p.h"
Michal Klocek
Refactors layout...
r1965 #include "charttitle_p.h"
#include "chartbackground_p.h"
Michal Klocek
Refactors layout:...
r2105 #include <QDebug>
Michal Klocek
Adds missing license headers
r1535
Michal Klocek
Refactors layout managment...
r1534 QTCOMMERCIALCHART_BEGIN_NAMESPACE
Miikka Heikkinen
Fix label truncate issues with multiple axes...
r2411 static const qreal maxAxisPortion = 0.4;
Michal Klocek
Refactors layout...
r1965
Jani Honkonen
src folder: another massive victory for coding style police
r2131 ChartLayout::ChartLayout(ChartPresenter *presenter)
: m_presenter(presenter),
m_margins(20, 20, 20, 20),
m_minChartRect(0, 0, 200, 200)
Michal Klocek
Refactors layout managment...
r1534 {
}
ChartLayout::~ChartLayout()
{
}
Jani Honkonen
src folder: another massive victory for coding style police
r2131 void ChartLayout::setGeometry(const QRectF &rect)
Michal Klocek
Refactors layout managment...
r1534 {
Jani Honkonen
Implement QChartView::setChart()
r2056 if (!rect.isValid())
return;
Michal Klocek
Fixes blinking and minimal false size for legend
r1538
Jani Honkonen
src folder: another massive victory for coding style police
r2131 QList<ChartAxis *> axes = m_presenter->axisItems();
ChartTitle *title = m_presenter->titleElement();
QLegend *legend = m_presenter->legend();
ChartBackground *background = m_presenter->backgroundElement();
Michal Klocek
Refactors layout managment...
r1534
Jani Honkonen
src folder: another massive victory for coding style police
r2131 QRectF contentGeometry = calculateBackgroundGeometry(rect, background);
Michal Klocek
Refactors layout managment...
r1534
Michal Klocek
Refactors layout...
r1965 contentGeometry = calculateContentGeometry(contentGeometry);
Michal Klocek
Bugfixes for layout...
r1837
Jani Honkonen
src folder: another massive victory for coding style police
r2131 if (title && title->isVisible())
contentGeometry = calculateTitleGeometry(contentGeometry, title);
Michal Klocek
Refactors layout managment...
r1534
Jani Honkonen
src folder: another massive victory for coding style police
r2131 if (legend->isAttachedToChart() && legend->isVisible())
contentGeometry = calculateLegendGeometry(contentGeometry, legend);
Michal Klocek
Refactors layout managment...
r1534
Jani Honkonen
src folder: another massive victory for coding style police
r2131 contentGeometry = calculateAxisGeometry(contentGeometry, axes);
Michal Klocek
Refactors layout...
r1965
Michal Klocek
Refactors internals...
r2273 m_presenter->setGeometry(contentGeometry);
Michal Klocek
Refactors layout...
r1965
QGraphicsLayout::setGeometry(rect);
}
Jani Honkonen
src folder: another massive victory for coding style police
r2131 QRectF ChartLayout::calculateContentGeometry(const QRectF &geometry) const
Michal Klocek
Refactors layout...
r1965 {
Jani Honkonen
src folder: another massive victory for coding style police
r2131 return geometry.adjusted(m_margins.left(), m_margins.top(), -m_margins.right(), -m_margins.bottom());
Michal Klocek
Refactors layout...
r1965 }
Jani Honkonen
src folder: another massive victory for coding style police
r2131 QRectF ChartLayout::calculateContentMinimum(const QRectF &minimum) const
Michal Klocek
Refactors layout...
r1965 {
Jani Honkonen
src folder: another massive victory for coding style police
r2131 return minimum.adjusted(0, 0, m_margins.left() + m_margins.right(), m_margins.top() + m_margins.bottom());
Michal Klocek
Refactors layout...
r1965 }
Michal Klocek
Refactors layout managment...
r1534
Michal Klocek
Refactors layout...
r1965
Jani Honkonen
src folder: another massive victory for coding style police
r2131 QRectF ChartLayout::calculateBackgroundGeometry(const QRectF &geometry, ChartBackground *background) const
Michal Klocek
Refactors layout...
r1965 {
qreal left, top, right, bottom;
getContentsMargins(&left, &top, &right, &bottom);
Jani Honkonen
src folder: another massive victory for coding style police
r2131 QRectF backgroundGeometry = geometry.adjusted(left, top, -right, -bottom);
if (background)
background->setRect(backgroundGeometry);
Michal Klocek
Refactors layout...
r1965 return backgroundGeometry;
}
Jani Honkonen
src folder: another massive victory for coding style police
r2131 QRectF ChartLayout::calculateBackgroundMinimum(const QRectF &minimum) const
Michal Klocek
Refactors layout...
r1965 {
qreal left, top, right, bottom;
getContentsMargins(&left, &top, &right, &bottom);
Jani Honkonen
src folder: another massive victory for coding style police
r2131 return minimum.adjusted(0, 0, left + right, top + bottom);
Michal Klocek
Refactors layout...
r1965 }
Michal Klocek
Refactors layout:...
r2105
Jani Honkonen
src folder: another massive victory for coding style police
r2131 QRectF ChartLayout::calculateAxisGeometry(const QRectF &geometry, const QList<ChartAxis *>& axes) const
Michal Klocek
Refactors layout...
r1965 {
Michal Klocek
Updates axis drawing code...
r2133 QSizeF left(0,0);
QSizeF minLeft(0,0);
QSizeF right(0,0);
QSizeF minRight(0,0);
QSizeF bottom(0,0);
QSizeF minBottom(0,0);
QSizeF top(0,0);
QSizeF minTop(0,0);
Michal Klocek
Refactors layout:...
r2105 int leftCount = 0;
int rightCount = 0;
int topCount = 0;
int bottomCount = 0;
Jani Honkonen
src folder: another massive victory for coding style police
r2131 foreach (ChartAxis *axis , axes) {
Michal Klocek
Refactors layout:...
r2105
Jani Honkonen
src folder: another massive victory for coding style police
r2131 if (!axis->isVisible())
continue;
Michal Klocek
Refactors layout:...
r2105
Michal Klocek
Refactors internals...
r2273
Michal Klocek
Updates axis drawing code...
r2133 QSizeF size = axis->effectiveSizeHint(Qt::PreferredSize);
//this is used to get single thick font size
QSizeF minSize = axis->effectiveSizeHint(Qt::MinimumSize);
Michal Klocek
Refactors layout:...
r2105
Jani Honkonen
src folder: another massive victory for coding style police
r2131 switch (axis->alignment()) {
Michal Klocek
Refactors layout:...
r2105 case Qt::AlignLeft:
Michal Klocek
Updates axis drawing code...
r2133 left.setWidth(left.width()+size.width());
left.setHeight(qMax(left.height(),size.height()));
minLeft.setWidth(minLeft.width()+minSize.width());
minLeft.setHeight(qMax(minLeft.height(),minSize.height()));
leftCount++;
break;
Michal Klocek
Refactors layout:...
r2105 case Qt::AlignRight:
Michal Klocek
Updates axis drawing code...
r2133 right.setWidth(right.width()+size.width());
right.setHeight(qMax(right.height(),size.height()));
minRight.setWidth(minRight.width()+minSize.width());
minRight.setHeight(qMax(minRight.height(),minSize.height()));
Michal Klocek
Refactors layout:...
r2105 rightCount++;
break;
case Qt::AlignTop:
Michal Klocek
Updates axis drawing code...
r2133 top.setWidth(qMax(top.width(),size.width()));
top.setHeight(top.height()+size.height());
minTop.setWidth(qMax(minTop.width(),minSize.width()));
minTop.setHeight(minTop.height()+minSize.height());
Michal Klocek
Refactors layout:...
r2105 topCount++;
break;
case Qt::AlignBottom:
Jani Honkonen
src folder: another massive victory for coding style police
r2131 bottom.setWidth(qMax(bottom.width(), size.width()));
Michal Klocek
Refactors layout:...
r2105 bottom.setHeight(bottom.height() + size.height());
Michal Klocek
Updates axis drawing code...
r2133 minBottom.setWidth(qMax(minBottom.width(),minSize.width()));
minBottom.setHeight(minBottom.height() + minSize.height());
Michal Klocek
Refactors layout:...
r2105 bottomCount++;
break;
Michal Klocek
Refactors internals...
r2273 default:
qWarning()<<"Axis is without alignment !";
break;
Michal Klocek
Refactors layout...
r1965 }
Michal Klocek
Refactors layout managment...
r1534 }
Miikka Heikkinen
Fix label truncate issues with multiple axes...
r2411 int totalVerticalAxes = leftCount + rightCount;
qreal leftSqueezeRatio = 1.0;
qreal rightSqueezeRatio = 1.0;
qreal vratio = 0;
Michal Klocek
Updates axis drawing code...
r2133
Miikka Heikkinen
Fix label truncate issues with multiple axes...
r2411 if (totalVerticalAxes > 0)
vratio = (maxAxisPortion * geometry.width()) / totalVerticalAxes;
if (leftCount > 0) {
int maxWidth = vratio * leftCount;
if (left.width() > maxWidth) {
leftSqueezeRatio = maxWidth / left.width();
left.setWidth(maxWidth);
}
}
if (rightCount > 0) {
int maxWidth = vratio * rightCount;
if (right.width() > maxWidth) {
rightSqueezeRatio = maxWidth / right.width();
right.setWidth(maxWidth);
}
}
int totalHorizontalAxes = topCount + bottomCount;
qreal topSqueezeRatio = 1.0;
qreal bottomSqueezeRatio = 1.0;
qreal hratio = 0;
if (totalHorizontalAxes > 0)
hratio = (maxAxisPortion * geometry.height()) / totalHorizontalAxes;
if (topCount > 0) {
int maxHeight = hratio * topCount;
if (top.height() > maxHeight) {
topSqueezeRatio = maxHeight / top.height();
top.setHeight(maxHeight);
}
}
if (bottomCount > 0) {
int maxHeight = hratio * bottomCount;
if (bottom.height() > maxHeight) {
bottomSqueezeRatio = maxHeight / bottom.height();
bottom.setHeight(maxHeight);
}
}
Michal Klocek
Refactors layout:...
r2105
Michal Klocek
minAxisLayout increased by 1
r2354 qreal minHeight = qMax(minLeft.height(),minRight.height()) + 1;
qreal minWidth = qMax(minTop.width(),minBottom.width()) + 1;
Michal Klocek
Updates axis drawing code...
r2133
QRectF chartRect = geometry.adjusted(qMax(left.width(),minWidth/2), qMax(top.height(), minHeight/2),-qMax(right.width(),minWidth/2),-qMax(bottom.height(),minHeight/2));
Michal Klocek
Refactors layout:...
r2105
Jani Honkonen
src folder: another massive victory for coding style police
r2131 qreal leftOffset = 0;
qreal rightOffset = 0;
qreal topOffset = 0;
qreal bottomOffset = 0;
Michal Klocek
Refactors layout:...
r2105
Michal Klocek
Refactors internals...
r2273 foreach(ChartElement *axisElement , axes) {
//TODO fixme
ChartAxis* axis = qobject_cast<ChartAxis*>(axisElement);
Michal Klocek
Refactors layout:...
r2105
Jani Honkonen
src folder: another massive victory for coding style police
r2131 if (!axis->isVisible())
continue;
Michal Klocek
Refactors layout:...
r2105
Michal Klocek
Updates axis drawing code...
r2133 QSizeF size = axis->effectiveSizeHint(Qt::PreferredSize);
Michal Klocek
Refactors layout:...
r2105
Michal Klocek
Updates axis drawing code...
r2133 switch(axis->alignment()){
case Qt::AlignLeft:{
Miikka Heikkinen
Fix label truncate issues with multiple axes...
r2411 qreal width = size.width();
if (leftSqueezeRatio < 1.0)
width *= leftSqueezeRatio;
Michal Klocek
Updates axis drawing code...
r2133 leftOffset+=width;
axis->setGeometry(QRect(chartRect.left()-leftOffset, geometry.top(),width, geometry.bottom()),chartRect);
Michal Klocek
Refactors layout:...
r2105 break;
}
Michal Klocek
Updates axis drawing code...
r2133 case Qt::AlignRight:{
Miikka Heikkinen
Fix label truncate issues with multiple axes...
r2411 qreal width = size.width();
if (rightSqueezeRatio < 1.0)
width *= rightSqueezeRatio;
Michal Klocek
Updates axis drawing code...
r2133 axis->setGeometry(QRect(chartRect.right()+rightOffset,geometry.top(),width,geometry.bottom()),chartRect);
rightOffset+=width;
Michal Klocek
Refactors layout:...
r2105 break;
}
Miikka Heikkinen
Fix label truncate issues with multiple axes...
r2411 case Qt::AlignTop: {
qreal height = size.height();
if (topSqueezeRatio < 1.0)
height *= topSqueezeRatio;
axis->setGeometry(QRect(geometry.left(), chartRect.top() - topOffset - height, geometry.width(), height), chartRect);
topOffset += height;
Michal Klocek
Refactors layout:...
r2105 break;
Miikka Heikkinen
Fix label truncate issues with multiple axes...
r2411 }
Michal Klocek
Refactors layout:...
r2105 case Qt::AlignBottom:
Miikka Heikkinen
Fix label truncate issues with multiple axes...
r2411 qreal height = size.height();
if (bottomSqueezeRatio < 1.0)
height *= bottomSqueezeRatio;
axis->setGeometry(QRect(geometry.left(), chartRect.bottom() + bottomOffset, geometry.width(), height), chartRect);
bottomOffset += height;
Michal Klocek
Refactors layout:...
r2105 break;
Marek Rosa
Multiaxis support...
r2093 }
Michal Klocek
Refactors layout...
r1965 }
Michal Klocek
Implements minimumMargins...
r1883
Michal Klocek
Refactors layout:...
r2105 return chartRect;
Michal Klocek
Refactors layout...
r1965 }
Michal Klocek
Refactors layout managment...
r1534
Jani Honkonen
src folder: another massive victory for coding style police
r2131 QRectF ChartLayout::calculateAxisMinimum(const QRectF &minimum, const QList<ChartAxis *>& axes) const
Michal Klocek
Refactors layout...
r1965 {
Michal Klocek
Refactors layout:...
r2105 QSizeF left;
QSizeF right;
QSizeF bottom;
QSizeF top;
Michal Klocek
Refactors internals...
r2273 foreach (ChartAxis *axis, axes) {
Michal Klocek
Refactors layout:...
r2105
QSizeF size = axis->effectiveSizeHint(Qt::MinimumSize);
Jani Honkonen
src folder: another massive victory for coding style police
r2131 if (!axis->isVisible())
continue;
Michal Klocek
Refactors layout:...
r2105
Jani Honkonen
src folder: another massive victory for coding style police
r2131 switch (axis->alignment()) {
case Qt::AlignLeft:
left.setWidth(left.width() + size.width());
left.setHeight(qMax(left.height() * 2, size.height()));
Michal Klocek
Refactors layout:...
r2105 break;
Jani Honkonen
src folder: another massive victory for coding style police
r2131 case Qt::AlignRight:
right.setWidth(right.width() + size.width());
right.setHeight(qMax(right.height() * 2, size.height()));
Michal Klocek
Refactors layout:...
r2105 break;
Jani Honkonen
src folder: another massive victory for coding style police
r2131 case Qt::AlignTop:
top.setWidth(qMax(top.width(), size.width()));
top.setHeight(top.height() + size.height());
Michal Klocek
Refactors layout:...
r2105 break;
Jani Honkonen
src folder: another massive victory for coding style police
r2131 case Qt::AlignBottom:
bottom.setWidth(qMax(bottom.width(), size.width()));
Michal Klocek
Refactors layout:...
r2105 bottom.setHeight(bottom.height() + size.height());
break;
}
Michal Klocek
Refactors layout...
r1965 }
Jani Honkonen
src folder: another massive victory for coding style police
r2131 return minimum.adjusted(0, 0, left.width() + right.width() + qMax(top.width(), bottom.width()), top.height() + bottom.height() + qMax(left.height(), right.height()));
Michal Klocek
Refactors layout...
r1965 }
Michal Klocek
Refactors layout managment...
r1534
Jani Honkonen
src folder: another massive victory for coding style police
r2131 QRectF ChartLayout::calculateLegendGeometry(const QRectF &geometry, QLegend *legend) const
Michal Klocek
Refactors layout...
r1965 {
Jani Honkonen
src folder: another massive victory for coding style police
r2131 QSizeF size = legend->effectiveSizeHint(Qt::PreferredSize, QSizeF(-1, -1));
Michal Klocek
Refactors layout...
r1965 QRectF legendRect;
QRectF result;
Michal Klocek
Implements minimumMargins...
r1883
Michal Klocek
Refactors layout...
r1965 switch (legend->alignment()) {
Michal Klocek
Refactors layout:...
r2105 case Qt::AlignTop: {
Jani Honkonen
src folder: another massive victory for coding style police
r2131 legendRect = QRectF(geometry.topLeft(), QSizeF(geometry.width(), size.height()));
result = geometry.adjusted(0, legendRect.height(), 0, 0);
Marek Rosa
Multiaxis support...
r2093 break;
Michal Klocek
Refactors layout:...
r2105 }
case Qt::AlignBottom: {
Jani Honkonen
src folder: another massive victory for coding style police
r2131 legendRect = QRectF(QPointF(geometry.left(), geometry.bottom() - size.height()), QSizeF(geometry.width(), size.height()));
result = geometry.adjusted(0, 0, 0, -legendRect.height());
Marek Rosa
Multiaxis support...
r2093 break;
Michal Klocek
Refactors layout:...
r2105 }
Marek Rosa
Multiaxis support...
r2093 case Qt::AlignLeft: {
Miikka Heikkinen
Fix label truncate issues with multiple axes...
r2411 qreal width = qMin(size.width(), geometry.width() * maxAxisPortion);
Jani Honkonen
src folder: another massive victory for coding style police
r2131 legendRect = QRectF(geometry.topLeft(), QSizeF(width, geometry.height()));
result = geometry.adjusted(width, 0, 0, 0);
Marek Rosa
Multiaxis support...
r2093 break;
}
case Qt::AlignRight: {
Miikka Heikkinen
Fix label truncate issues with multiple axes...
r2411 qreal width = qMin(size.width(), geometry.width() * maxAxisPortion);
Jani Honkonen
src folder: another massive victory for coding style police
r2131 legendRect = QRectF(QPointF(geometry.right() - width, geometry.top()), QSizeF(width, geometry.height()));
result = geometry.adjusted(0, 0, -width, 0);
Marek Rosa
Multiaxis support...
r2093 break;
}
Michal Klocek
Refactors layout:...
r2105 default: {
Jani Honkonen
src folder: another massive victory for coding style police
r2131 legendRect = QRectF(0, 0, 0, 0);
Marek Rosa
Multiaxis support...
r2093 result = geometry;
break;
}
Michal Klocek
Refactors layout:...
r2105 }
Michal Klocek
Refactors layout managment...
r1534
Michal Klocek
Refactors layout...
r1965 legend->setGeometry(legendRect);
Michal Klocek
Refactors layout managment...
r1534
Michal Klocek
Refactors layout...
r1965 return result;
}
Michal Klocek
Refactors layout managment...
r1534
Jani Honkonen
src folder: another massive victory for coding style police
r2131 QRectF ChartLayout::calculateLegendMinimum(const QRectF &geometry, QLegend *legend) const
Michal Klocek
Refactors layout:...
r2105 {
Jani Honkonen
src folder: another massive victory for coding style police
r2131 QSizeF minSize = legend->effectiveSizeHint(Qt::MinimumSize, QSizeF(-1, -1));
return geometry.adjusted(0, 0, minSize.width(), minSize.height());
Michal Klocek
Refactors layout:...
r2105 }
Jani Honkonen
src folder: another massive victory for coding style police
r2131 QRectF ChartLayout::calculateTitleGeometry(const QRectF &geometry, ChartTitle *title) const
Michal Klocek
Refactors layout...
r1965 {
Marek Rosa
Multiaxis support...
r2093 title->setGeometry(geometry);
QPointF center = geometry.center() - title->boundingRect().center();
Michal Klocek
Updates axis drawing code...
r2133 title->setPos(center.x(),title->pos().y());
return geometry.adjusted(0,title->boundingRect().height()+1,0,0);
Michal Klocek
Refactors layout managment...
r1534 }
Jani Honkonen
src folder: another massive victory for coding style police
r2131 QRectF ChartLayout::calculateTitleMinimum(const QRectF &minimum, ChartTitle *title) const
Michal Klocek
Refactors layout...
r1965 {
Marek Rosa
Multiaxis support...
r2093 QSizeF min = title->sizeHint(Qt::MinimumSize);
Jani Honkonen
src folder: another massive victory for coding style police
r2131 return minimum.adjusted(0, 0, min.width(), min.height());
Michal Klocek
Refactors layout...
r1965 }
Michal Klocek
Refactors layout managment...
r1534
Jani Honkonen
src folder: another massive victory for coding style police
r2131 QSizeF ChartLayout::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
Michal Klocek
Refactors layout managment...
r1534 {
Q_UNUSED(constraint);
Jani Honkonen
src folder: another massive victory for coding style police
r2131 if (which == Qt::MinimumSize) {
QList<ChartAxis *> axes = m_presenter->axisItems();
ChartTitle *title = m_presenter->titleElement();
QLegend *legend = m_presenter->legend();
QRectF minimumRect(0, 0, 0, 0);
Michal Klocek
Refactors layout...
r1965 minimumRect = calculateBackgroundMinimum(minimumRect);
minimumRect = calculateContentMinimum(minimumRect);
Jani Honkonen
src folder: another massive victory for coding style police
r2131 minimumRect = calculateTitleMinimum(minimumRect, title);
minimumRect = calculateLegendMinimum(minimumRect, legend);
minimumRect = calculateAxisMinimum(minimumRect, axes);
Michal Klocek
Refactors layout:...
r2105 return minimumRect.united(m_minChartRect).size().toSize();
Jani Honkonen
src folder: another massive victory for coding style police
r2131 }
return QSize(-1, -1);
Michal Klocek
Refactors layout managment...
r1534 }
Jani Honkonen
src folder: another massive victory for coding style police
r2131 void ChartLayout::setMargins(const QMargins &margins)
Michal Klocek
Refactors layout managment...
r1534 {
Jani Honkonen
src folder: another massive victory for coding style police
r2131 if (m_margins != margins) {
Michal Klocek
Refactors layout...
r1965 m_margins = margins;
Michal Klocek
Refactors layout managment...
r1534 updateGeometry();
}
}
Michal Klocek
Refactors layout...
r1965 QMargins ChartLayout::margins() const
{
return m_margins;
}
Michal Klocek
Refactors layout managment...
r1534 QTCOMMERCIALCHART_END_NAMESPACE