summaryrefslogtreecommitdiffstats
path: root/src/legend/legendlayout.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/legend/legendlayout.cpp')
-rw-r--r--src/legend/legendlayout.cpp506
1 files changed, 0 insertions, 506 deletions
diff --git a/src/legend/legendlayout.cpp b/src/legend/legendlayout.cpp
deleted file mode 100644
index f6feed1a..00000000
--- a/src/legend/legendlayout.cpp
+++ /dev/null
@@ -1,506 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 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 Enterprise Charts Add-on.
-**
-** $QT_BEGIN_LICENSE$
-** Licensees holding valid Qt Enterprise licenses may use this file in
-** accordance with the Qt Enterprise 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$
-**
-****************************************************************************/
-
-#include "legendlayout_p.h"
-#include "chartpresenter_p.h"
-#include "qlegend_p.h"
-#include "abstractchartlayout_p.h"
-
-#include "qlegendmarker_p.h"
-#include "legendmarkeritem_p.h"
-#include "qlegendmarker.h"
-
-QTCOMMERCIALCHART_BEGIN_NAMESPACE
-
-LegendLayout::LegendLayout(QLegend *legend)
- : m_legend(legend),
- m_offsetX(0),
- m_offsetY(0)
-{
-
-}
-
-LegendLayout::~LegendLayout()
-{
-
-}
-
-void LegendLayout::setOffset(qreal x, qreal y)
-{
- bool scrollHorizontal = true;
- switch (m_legend->alignment()) {
- case Qt::AlignTop:
- case Qt::AlignBottom:
- scrollHorizontal = true;
- break;
- case Qt::AlignLeft:
- case Qt::AlignRight:
- scrollHorizontal = false;
- break;
- }
-
- // If detached, the scrolling direction is vertical instead of horizontal and vice versa.
- if (!m_legend->isAttachedToChart())
- scrollHorizontal = !scrollHorizontal;
-
- QRectF boundingRect = geometry();
- qreal left, top, right, bottom;
- getContentsMargins(&left, &top, &right, &bottom);
- boundingRect.adjust(left, top, -right, -bottom);
-
- // Limit offset between m_minOffset and m_maxOffset
- if (scrollHorizontal) {
- if (m_width <= boundingRect.width())
- return;
-
- if (x != m_offsetX) {
- m_offsetX = qBound(m_minOffsetX, x, m_maxOffsetX);
- m_legend->d_ptr->items()->setPos(-m_offsetX, boundingRect.top());
- }
- } else {
- if (m_height <= boundingRect.height())
- return;
-
- if (y != m_offsetY) {
- m_offsetY = qBound(m_minOffsetY, y, m_maxOffsetY);
- m_legend->d_ptr->items()->setPos(boundingRect.left(), -m_offsetY);
- }
- }
-}
-
-QPointF LegendLayout::offset() const
-{
- return QPointF(m_offsetX, m_offsetY);
-}
-
-void LegendLayout::invalidate()
-{
- QGraphicsLayout::invalidate();
- if (m_legend->isAttachedToChart())
- m_legend->d_ptr->m_presenter->layout()->invalidate();
-}
-
-void LegendLayout::setGeometry(const QRectF &rect)
-{
- m_legend->d_ptr->items()->setVisible(m_legend->isVisible());
-
- QGraphicsLayout::setGeometry(rect);
-
- if (m_legend->isAttachedToChart())
- setAttachedGeometry(rect);
- else
- setDettachedGeometry(rect);
-}
-
-void LegendLayout::setAttachedGeometry(const QRectF &rect)
-{
- if (!rect.isValid())
- return;
-
- qreal oldOffsetX = m_offsetX;
- qreal oldOffsetY = m_offsetY;
- m_offsetX = 0;
- m_offsetY = 0;
-
- QSizeF size(0, 0);
-
- if (m_legend->d_ptr->markers().isEmpty()) {
- return;
- }
-
- m_width = 0;
- m_height = 0;
-
- qreal left, top, right, bottom;
- getContentsMargins(&left, &top, &right, &bottom);
-
- QRectF geometry = rect.adjusted(left, top, -right, -bottom);
-
- switch(m_legend->alignment()) {
- case Qt::AlignTop:
- case Qt::AlignBottom: {
- // Calculate the space required for items and add them to a sorted list.
- qreal markerItemsWidth = 0;
- qreal itemMargins = 0;
- QList<LegendWidthStruct *> legendWidthList;
- foreach (QLegendMarker *marker, m_legend->d_ptr->markers()) {
- LegendMarkerItem *item = marker->d_ptr->item();
- if (item->isVisible()) {
- QSizeF dummySize;
- qreal itemWidth = item->sizeHint(Qt::PreferredSize, dummySize).width();
- LegendWidthStruct *structItem = new LegendWidthStruct;
- structItem->item = item;
- structItem->width = itemWidth;
- legendWidthList.append(structItem);
- markerItemsWidth += itemWidth;
- itemMargins += marker->d_ptr->item()->m_margin;
- }
- }
- qSort(legendWidthList.begin(), legendWidthList.end(), widthLongerThan);
-
- // If the items would occupy more space than is available, start truncating them
- // from the longest one.
- qreal availableGeometry = geometry.width() - right - left * 2 - itemMargins;
- if (markerItemsWidth >= availableGeometry && legendWidthList.count() > 0) {
- bool truncated(false);
- int count = legendWidthList.count();
- for (int i = 1; i < count; i++) {
- int truncateIndex = i - 1;
-
- while (legendWidthList.at(truncateIndex)->width >= legendWidthList.at(i)->width
- && !truncated) {
- legendWidthList.at(truncateIndex)->width--;
- markerItemsWidth--;
- if (i > 1) {
- // Truncate the items that are before the truncated one in the list.
- for (int j = truncateIndex - 1; j >= 0; j--) {
- if (legendWidthList.at(truncateIndex)->width
- < legendWidthList.at(j)->width) {
- legendWidthList.at(j)->width--;
- markerItemsWidth--;
- }
- }
- }
- if (markerItemsWidth < availableGeometry)
- truncated = true;
- }
- // Truncate the last item if needed.
- if (i == count - 1) {
- if (legendWidthList.at(count - 1)->width
- > legendWidthList.at(truncateIndex)->width) {
- legendWidthList.at(count - 1)->width--;
- markerItemsWidth--;
- }
- }
-
- if (truncated)
- break;
- }
- // Items are of same width and all of them need to be truncated
- // or there is just one item that is truncated.
- while (markerItemsWidth >= availableGeometry) {
- for (int i = 0; i < count; i++) {
- legendWidthList.at(i)->width--;
- markerItemsWidth--;
- }
- }
- }
-
- QPointF point(0,0);
-
- int markerCount = m_legend->d_ptr->markers().count();
- for (int i = 0; i < markerCount; i++) {
- QLegendMarker *marker;
- if (m_legend->d_ptr->m_reverseMarkers)
- marker = m_legend->d_ptr->markers().at(markerCount - 1 - i);
- else
- marker = m_legend->d_ptr->markers().at(i);
- LegendMarkerItem *item = marker->d_ptr->item();
- if (item->isVisible()) {
- QRectF itemRect = geometry;
- qreal availableWidth = 0;
- for (int i = 0; i < legendWidthList.size(); ++i) {
- if (legendWidthList.at(i)->item == item) {
- availableWidth = legendWidthList.at(i)->width;
- break;
- }
- }
- itemRect.setWidth(availableWidth);
- item->setGeometry(itemRect);
- item->setPos(point.x(),geometry.height()/2 - item->boundingRect().height()/2);
- const QRectF &rect = item->boundingRect();
- size = size.expandedTo(rect.size());
- qreal w = rect.width();
- m_width = m_width + w - item->m_margin;
- point.setX(point.x() + w);
- }
- }
- // Delete structs from the container
- qDeleteAll(legendWidthList);
-
- if (m_width < geometry.width())
- m_legend->d_ptr->items()->setPos(geometry.width() / 2 - m_width / 2, geometry.top());
- else
- m_legend->d_ptr->items()->setPos(geometry.topLeft());
- m_height = size.height();
- }
- break;
- case Qt::AlignLeft:
- case Qt::AlignRight: {
- QPointF point(0,0);
- int markerCount = m_legend->d_ptr->markers().count();
- for (int i = 0; i < markerCount; i++) {
- QLegendMarker *marker;
- if (m_legend->d_ptr->m_reverseMarkers)
- marker = m_legend->d_ptr->markers().at(markerCount - 1 - i);
- else
- marker = m_legend->d_ptr->markers().at(i);
- LegendMarkerItem *item = marker->d_ptr->item();
- if (item->isVisible()) {
- item->setGeometry(geometry);
- item->setPos(point);
- const QRectF &rect = item->boundingRect();
- qreal h = rect.height();
- size = size.expandedTo(rect.size());
- m_height+=h;
- point.setY(point.y() + h);
- }
- }
-
- if (m_height < geometry.height())
- m_legend->d_ptr->items()->setPos(geometry.left(), geometry.height() / 2 - m_height / 2);
- else
- m_legend->d_ptr->items()->setPos(geometry.topLeft());
- m_width = size.width();
- break;
- }
- }
-
- m_minOffsetX = -left;
- m_minOffsetY = - top;
- m_maxOffsetX = m_width - geometry.width() - right;
- m_maxOffsetY = m_height - geometry.height() - bottom;
-
- setOffset(oldOffsetX, oldOffsetY);
-}
-
-void LegendLayout::setDettachedGeometry(const QRectF &rect)
-{
- if (!rect.isValid())
- return;
-
- // Detached layout is different.
- // In detached mode legend may have multiple rows and columns, so layout calculations
- // differ a log from attached mode.
- // Also the scrolling logic is bit different.
-
- qreal oldOffsetX = m_offsetX;
- qreal oldOffsetY = m_offsetY;
- m_offsetX = 0;
- m_offsetY = 0;
-
- qreal left, top, right, bottom;
- getContentsMargins(&left, &top, &right, &bottom);
- QRectF geometry = rect.adjusted(left, top, -right, -bottom);
-
- QSizeF size(0, 0);
-
- QList<QLegendMarker *> markers = m_legend->d_ptr->markers();
-
- if (markers.isEmpty())
- return;
-
- switch (m_legend->alignment()) {
- case Qt::AlignTop: {
- QPointF point(0, 0);
- m_width = 0;
- m_height = 0;
- for (int i = 0; i < markers.count(); i++) {
- LegendMarkerItem *item = markers.at(i)->d_ptr->item();
- if (item->isVisible()) {
- item->setGeometry(geometry);
- item->setPos(point.x(),point.y());
- const QRectF &boundingRect = item->boundingRect();
- qreal w = boundingRect.width();
- qreal h = boundingRect.height();
- m_width = qMax(m_width,w);
- m_height = qMax(m_height,h);
- point.setX(point.x() + w);
- if (point.x() + w > geometry.left() + geometry.width() - right) {
- // Next item would go off rect.
- point.setX(0);
- point.setY(point.y() + h);
- if (i+1 < markers.count()) {
- m_height += h;
- }
- }
- }
- }
- m_legend->d_ptr->items()->setPos(geometry.topLeft());
-
- m_minOffsetX = -left;
- m_minOffsetY = -top;
- m_maxOffsetX = m_width - geometry.width() - right;
- m_maxOffsetY = m_height - geometry.height() - bottom;
- }
- break;
- case Qt::AlignBottom: {
- QPointF point(0, geometry.height());
- m_width = 0;
- m_height = 0;
- for (int i = 0; i < markers.count(); i++) {
- LegendMarkerItem *item = markers.at(i)->d_ptr->item();
- if (item->isVisible()) {
- item->setGeometry(geometry);
- const QRectF &boundingRect = item->boundingRect();
- qreal w = boundingRect.width();
- qreal h = boundingRect.height();
- m_width = qMax(m_width,w);
- m_height = qMax(m_height,h);
- item->setPos(point.x(),point.y() - h);
- point.setX(point.x() + w);
- if (point.x() + w > geometry.left() + geometry.width() - right) {
- // Next item would go off rect.
- point.setX(0);
- point.setY(point.y() - h);
- if (i+1 < markers.count()) {
- m_height += h;
- }
- }
- }
- }
- m_legend->d_ptr->items()->setPos(geometry.topLeft());
-
- m_minOffsetX = -left;
- m_minOffsetY = -m_height + geometry.height() - top;
- m_maxOffsetX = m_width - geometry.width() - right;
- m_maxOffsetY = -bottom;
- }
- break;
- case Qt::AlignLeft: {
- QPointF point(0, 0);
- m_width = 0;
- m_height = 0;
- qreal maxWidth = 0;
- for (int i = 0; i < markers.count(); i++) {
- LegendMarkerItem *item = markers.at(i)->d_ptr->item();
- if (item->isVisible()) {
- item->setGeometry(geometry);
- const QRectF &boundingRect = item->boundingRect();
- qreal w = boundingRect.width();
- qreal h = boundingRect.height();
- m_height = qMax(m_height,h);
- maxWidth = qMax(maxWidth,w);
- item->setPos(point.x(),point.y());
- point.setY(point.y() + h);
- if (point.y() + h > geometry.bottom() - bottom) {
- // Next item would go off rect.
- point.setX(point.x() + maxWidth);
- point.setY(0);
- if (i+1 < markers.count()) {
- m_width += maxWidth;
- maxWidth = 0;
- }
- }
- }
- }
- m_width += maxWidth;
- m_legend->d_ptr->items()->setPos(geometry.topLeft());
-
- m_minOffsetX = -left;
- m_minOffsetY = -top;
- m_maxOffsetX = m_width - geometry.width() - right;
- m_maxOffsetY = m_height - geometry.height() - bottom;
- }
- break;
- case Qt::AlignRight: {
- QPointF point(geometry.width(), 0);
- m_width = 0;
- m_height = 0;
- qreal maxWidth = 0;
- for (int i = 0; i < markers.count(); i++) {
- LegendMarkerItem *item = markers.at(i)->d_ptr->item();
- if (item->isVisible()) {
- item->setGeometry(geometry);
- const QRectF &boundingRect = item->boundingRect();
- qreal w = boundingRect.width();
- qreal h = boundingRect.height();
- m_height = qMax(m_height,h);
- maxWidth = qMax(maxWidth,w);
- item->setPos(point.x() - w,point.y());
- point.setY(point.y() + h);
- if (point.y() + h > geometry.bottom()-bottom) {
- // Next item would go off rect.
- point.setX(point.x() - maxWidth);
- point.setY(0);
- if (i+1 < markers.count()) {
- m_width += maxWidth;
- maxWidth = 0;
- }
- }
- }
- }
- m_width += maxWidth;
- m_legend->d_ptr->items()->setPos(geometry.topLeft());
-
- m_minOffsetX = - m_width + geometry.width() - left;
- m_minOffsetY = -top;
- m_maxOffsetX = - right;
- m_maxOffsetY = m_height - geometry.height() - bottom;
- }
- break;
- default:
- break;
- }
-
- setOffset(oldOffsetX, oldOffsetY);
-}
-
-QSizeF LegendLayout::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
-{
- QSizeF size(0, 0);
- qreal left, top, right, bottom;
- getContentsMargins(&left, &top, &right, &bottom);
-
- if(constraint.isValid()) {
- foreach(QLegendMarker *marker, m_legend->d_ptr->markers()) {
- LegendMarkerItem *item = marker->d_ptr->item();
- size = size.expandedTo(item->effectiveSizeHint(which));
- }
- size = size.boundedTo(constraint);
- }
- else if (constraint.width() >= 0) {
- qreal width = 0;
- qreal height = 0;
- foreach(QLegendMarker *marker, m_legend->d_ptr->markers()) {
- LegendMarkerItem *item = marker->d_ptr->item();
- width+=item->effectiveSizeHint(which).width();
- height=qMax(height,item->effectiveSizeHint(which).height());
- }
-
- size = QSizeF(qMin(constraint.width(),width), height);
- }
- else if (constraint.height() >= 0) {
- qreal width = 0;
- qreal height = 0;
- foreach(QLegendMarker *marker, m_legend->d_ptr->markers()) {
- LegendMarkerItem *item = marker->d_ptr->item();
- width=qMax(width,item->effectiveSizeHint(which).width());
- height+=height,item->effectiveSizeHint(which).height();
- }
- size = QSizeF(width,qMin(constraint.height(),height));
- }
- else {
- foreach(QLegendMarker *marker, m_legend->d_ptr->markers()) {
- LegendMarkerItem *item = marker->d_ptr->item();
- size = size.expandedTo(item->effectiveSizeHint(which));
- }
- }
- size += QSize(left + right, top + bottom);
- return size;
-}
-
-bool LegendLayout::widthLongerThan(const LegendWidthStruct *item1,
- const LegendWidthStruct *item2)
-{
- return item1->width > item2->width;
-}
-
-QTCOMMERCIALCHART_END_NAMESPACE