diff options
Diffstat (limited to 'src/legend/legendlayout.cpp')
-rw-r--r-- | src/legend/legendlayout.cpp | 506 |
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 |