| /**************************************************************************** |
| ** |
| ** Copyright (C) 2016 The Qt Company Ltd. |
| ** Contact: https://www.qt.io/licensing/ |
| ** |
| ** This file is part of the Qt Data Visualization module of the Qt Toolkit. |
| ** |
| ** $QT_BEGIN_LICENSE:GPL$ |
| ** Commercial License Usage |
| ** Licensees holding valid commercial Qt licenses may use this file in |
| ** accordance with the commercial license agreement provided with the |
| ** Software or, alternatively, in accordance with the terms contained in |
| ** a written agreement between you and The Qt Company. For licensing terms |
| ** and conditions see https://www.qt.io/terms-conditions. For further |
| ** information use the contact form at https://www.qt.io/contact-us. |
| ** |
| ** GNU General Public License Usage |
| ** Alternatively, this file may be used under the terms of the GNU |
| ** General Public License version 3 or (at your option) any later version |
| ** approved by the KDE Free Qt Foundation. The licenses are as published by |
| ** the Free Software Foundation and appearing in the file LICENSE.GPL3 |
| ** included in the packaging of this file. Please review the following |
| ** information to ensure the GNU General Public License requirements will |
| ** be met: https://www.gnu.org/licenses/gpl-3.0.html. |
| ** |
| ** $QT_END_LICENSE$ |
| ** |
| ****************************************************************************/ |
| |
| #include "axisrendercache_p.h" |
| |
| #include <QtGui/QFontMetrics> |
| |
| QT_BEGIN_NAMESPACE_DATAVISUALIZATION |
| |
| AxisRenderCache::AxisRenderCache() |
| : m_type(QAbstract3DAxis::AxisTypeNone), |
| m_min(0.0f), |
| m_max(10.0f), |
| m_segmentCount(5), |
| m_subSegmentCount(1), |
| m_reversed(false), |
| m_font(QFont(QStringLiteral("Arial"))), |
| m_formatter(0), |
| m_ctrlFormatter(0), |
| m_drawer(0), |
| m_positionsDirty(true), |
| m_translate(0.0f), |
| m_scale(1.0f), |
| m_labelAutoRotation(0.0f), |
| m_titleVisible(false), |
| m_titleFixed(false) |
| { |
| } |
| |
| AxisRenderCache::~AxisRenderCache() |
| { |
| foreach (LabelItem *label, m_labelItems) |
| delete label; |
| m_titleItem.clear(); |
| |
| delete m_formatter; |
| } |
| |
| void AxisRenderCache::setDrawer(Drawer *drawer) |
| { |
| m_drawer = drawer; |
| m_font = m_drawer->font(); |
| if (m_drawer) |
| updateTextures(); |
| } |
| |
| void AxisRenderCache::setType(QAbstract3DAxis::AxisType type) |
| { |
| m_type = type; |
| |
| // If type is set, it means completely new axis instance, so clear all old data |
| m_labels.clear(); |
| m_title.clear(); |
| m_min = 0.0f; |
| m_max = 10.0f; |
| m_segmentCount = 5; |
| m_subSegmentCount = 1; |
| m_labelFormat.clear(); |
| |
| m_titleItem.clear(); |
| foreach (LabelItem *label, m_labelItems) |
| delete label; |
| m_labelItems.clear(); |
| } |
| |
| void AxisRenderCache::setTitle(const QString &title) |
| { |
| if (m_title != title) { |
| m_title = title; |
| // Generate axis label texture |
| if (m_drawer) |
| m_drawer->generateLabelItem(m_titleItem, title); |
| } |
| } |
| |
| void AxisRenderCache::setLabels(const QStringList &labels) |
| { |
| if (m_labels != labels) { |
| int newSize(labels.size()); |
| int oldSize(m_labels.size()); |
| |
| for (int i = newSize; i < oldSize; i++) |
| delete m_labelItems.takeLast(); |
| |
| m_labelItems.reserve(newSize); |
| |
| int widest = maxLabelWidth(labels); |
| |
| for (int i = 0; i < newSize; i++) { |
| if (i >= oldSize) |
| m_labelItems.append(new LabelItem); |
| if (m_drawer) { |
| if (labels.at(i).isEmpty()) { |
| m_labelItems[i]->clear(); |
| } else if (i >= oldSize || labels.at(i) != m_labels.at(i) |
| || m_labelItems[i]->size().width() != widest) { |
| m_drawer->generateLabelItem(*m_labelItems[i], labels.at(i), widest); |
| } |
| } |
| } |
| m_labels = labels; |
| } |
| } |
| |
| void AxisRenderCache::updateAllPositions() |
| { |
| // As long as grid and subgrid lines are drawn identically, we can further optimize |
| // by caching all grid and subgrid positions into a single vector. |
| // If subgrid lines are ever themed separately, this array will probably become obsolete. |
| if (m_formatter) { |
| int gridCount = m_formatter->gridPositions().size(); |
| int subGridCount = m_formatter->subGridPositions().size(); |
| int labelCount = m_formatter->labelPositions().size(); |
| int fullSize = gridCount + subGridCount; |
| |
| m_adjustedGridLinePositions.resize(fullSize); |
| m_adjustedLabelPositions.resize(labelCount); |
| int index = 0; |
| int grid = 0; |
| int label = 0; |
| float position = 0.0f; |
| for (; label < labelCount; label++) { |
| position = m_formatter->labelPositions().at(label); |
| if (m_reversed) |
| position = 1.0f - position; |
| m_adjustedLabelPositions[label] = position * m_scale + m_translate; |
| } |
| for (; grid < gridCount; grid++) { |
| position = m_formatter->gridPositions().at(grid); |
| if (m_reversed) |
| position = 1.0f - position; |
| m_adjustedGridLinePositions[index++] = position * m_scale + m_translate; |
| } |
| for (int subGrid = 0; subGrid < subGridCount; subGrid++) { |
| position = m_formatter->subGridPositions().at(subGrid); |
| if (m_reversed) |
| position = 1.0f - position; |
| m_adjustedGridLinePositions[index++] = position * m_scale + m_translate; |
| } |
| |
| m_positionsDirty = false; |
| } |
| } |
| |
| void AxisRenderCache::updateTextures() |
| { |
| m_font = m_drawer->font(); |
| |
| if (m_title.isEmpty()) |
| m_titleItem.clear(); |
| else |
| m_drawer->generateLabelItem(m_titleItem, m_title); |
| |
| int widest = maxLabelWidth(m_labels); |
| |
| for (int i = 0; i < m_labels.size(); i++) { |
| if (m_labels.at(i).isEmpty()) |
| m_labelItems[i]->clear(); |
| else |
| m_drawer->generateLabelItem(*m_labelItems[i], m_labels.at(i), widest); |
| } |
| } |
| |
| void AxisRenderCache::clearLabels() |
| { |
| m_titleItem.clear(); |
| for (int i = 0; i < m_labels.size(); i++) |
| m_labelItems[i]->clear(); |
| } |
| |
| int AxisRenderCache::maxLabelWidth(const QStringList &labels) const |
| { |
| int labelWidth = 0; |
| QFont labelFont = m_font; |
| labelFont.setPointSize(textureFontSize); |
| QFontMetrics labelFM(labelFont); |
| for (int i = 0; i < labels.size(); i++) { |
| int newWidth = labelFM.horizontalAdvance(labels.at(i)); |
| if (labelWidth < newWidth) |
| labelWidth = newWidth; |
| } |
| return labelWidth; |
| } |
| |
| QT_END_NAMESPACE_DATAVISUALIZATION |