Revision control
Copy as Markdown
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include "declarativeseries_p.h"
#include <QtCore/QMetaMethod>
QT_BEGIN_NAMESPACE
static void setSeriesGradient(QAbstract3DSeries *series, const ColorGradient &gradient,
GradientType type)
{
QLinearGradient newGradient;
QGradientStops stops;
QList<ColorGradientStop *> qmlstops = gradient.m_stops;
// Get sorted gradient stops
for (int i = 0; i < qmlstops.size(); i++) {
int j = 0;
while (j < stops.size() && stops.at(j).first < qmlstops[i]->position())
j++;
stops.insert(j, QGradientStop(qmlstops.at(i)->position(), qmlstops.at(i)->color()));
}
newGradient.setStops(stops);
switch (type) {
case GradientTypeBase:
series->setBaseGradient(newGradient);
break;
case GradientTypeSingle:
series->setSingleHighlightGradient(newGradient);
break;
case GradientTypeMulti:
series->setMultiHighlightGradient(newGradient);
break;
default: // Never goes here
break;
}
}
static void connectSeriesGradient(QAbstract3DSeries *series, ColorGradient *newGradient,
GradientType type, ColorGradient **memberGradient)
{
// connect new / disconnect old
if (newGradient != *memberGradient) {
if (*memberGradient)
QObject::disconnect(*memberGradient, 0, series, 0);
*memberGradient = newGradient;
int updatedIndex = newGradient->metaObject()->indexOfSignal("updated()");
QMetaMethod updateFunction = newGradient->metaObject()->method(updatedIndex);
int handleIndex = -1;
switch (type) {
case GradientTypeBase:
handleIndex = series->metaObject()->indexOfSlot("handleBaseGradientUpdate()");
break;
case GradientTypeSingle:
handleIndex = series->metaObject()->indexOfSlot("handleSingleHighlightGradientUpdate()");
break;
case GradientTypeMulti:
handleIndex = series->metaObject()->indexOfSlot("handleMultiHighlightGradientUpdate()");
break;
default: // Never goes here
break;
}
QMetaMethod handleFunction = series->metaObject()->method(handleIndex);
if (*memberGradient)
QObject::connect(*memberGradient, updateFunction, series, handleFunction);
}
if (*memberGradient)
setSeriesGradient(series, **memberGradient, type);
}
DeclarativeBar3DSeries::DeclarativeBar3DSeries(QObject *parent)
: QBar3DSeries(parent),
m_baseGradient(0),
m_singleHighlightGradient(0),
m_multiHighlightGradient(0),
m_dummyColors(false)
{
QObject::connect(this, &QBar3DSeries::selectedBarChanged, this,
&DeclarativeBar3DSeries::selectedBarChanged);
}
DeclarativeBar3DSeries::~DeclarativeBar3DSeries()
{
}
QQmlListProperty<QObject> DeclarativeBar3DSeries::seriesChildren()
{
return QQmlListProperty<QObject>(this, this, &DeclarativeBar3DSeries::appendSeriesChildren
, 0, 0, 0);
}
void DeclarativeBar3DSeries::appendSeriesChildren(QQmlListProperty<QObject> *list, QObject *element)
{
QBarDataProxy *proxy = qobject_cast<QBarDataProxy *>(element);
if (proxy)
reinterpret_cast<DeclarativeBar3DSeries *>(list->data)->setDataProxy(proxy);
}
void DeclarativeBar3DSeries::setSelectedBar(const QPointF &position)
{
QBar3DSeries::setSelectedBar(position.toPoint());
}
QPointF DeclarativeBar3DSeries::selectedBar() const
{
return QPointF(QBar3DSeries::selectedBar());
}
QPointF DeclarativeBar3DSeries::invalidSelectionPosition() const
{
return QPointF(QBar3DSeries::invalidSelectionPosition());
}
void DeclarativeBar3DSeries::setBaseGradient(ColorGradient *gradient)
{
connectSeriesGradient(this, gradient, GradientTypeBase, &m_baseGradient);
}
ColorGradient *DeclarativeBar3DSeries::baseGradient() const
{
return m_baseGradient;
}
void DeclarativeBar3DSeries::setSingleHighlightGradient(ColorGradient *gradient)
{
connectSeriesGradient(this, gradient, GradientTypeSingle, &m_singleHighlightGradient);
}
ColorGradient *DeclarativeBar3DSeries::singleHighlightGradient() const
{
return m_singleHighlightGradient;
}
void DeclarativeBar3DSeries::setMultiHighlightGradient(ColorGradient *gradient)
{
connectSeriesGradient(this, gradient, GradientTypeMulti, &m_multiHighlightGradient);
}
ColorGradient *DeclarativeBar3DSeries::multiHighlightGradient() const
{
return m_multiHighlightGradient;
}
QQmlListProperty<DeclarativeColor> DeclarativeBar3DSeries::rowColors()
{
return QQmlListProperty<DeclarativeColor>(this, this,
&DeclarativeBar3DSeries::appendRowColorsFunc,
&DeclarativeBar3DSeries::countRowColorsFunc,
&DeclarativeBar3DSeries::atRowColorsFunc,
&DeclarativeBar3DSeries::clearRowColorsFunc);
}
void DeclarativeBar3DSeries::appendRowColorsFunc(QQmlListProperty<DeclarativeColor> *list,
DeclarativeColor *color)
{
reinterpret_cast<DeclarativeBar3DSeries *>(list->data)->addColor(color);
}
qsizetype DeclarativeBar3DSeries::countRowColorsFunc(QQmlListProperty<DeclarativeColor> *list)
{
return reinterpret_cast<DeclarativeBar3DSeries *>(list->data)->colorList().size();
}
DeclarativeColor *DeclarativeBar3DSeries::atRowColorsFunc(QQmlListProperty<DeclarativeColor> *list,
qsizetype index)
{
return reinterpret_cast<DeclarativeBar3DSeries *>(list->data)->colorList().at(index);
}
void DeclarativeBar3DSeries::clearRowColorsFunc(QQmlListProperty<DeclarativeColor> *list)
{
reinterpret_cast<DeclarativeBar3DSeries *>(list->data)->clearColors();
}
void DeclarativeBar3DSeries::handleBaseGradientUpdate()
{
if (m_baseGradient)
setSeriesGradient(this, *m_baseGradient, GradientTypeBase);
}
void DeclarativeBar3DSeries::handleSingleHighlightGradientUpdate()
{
if (m_singleHighlightGradient)
setSeriesGradient(this, *m_singleHighlightGradient, GradientTypeSingle);
}
void DeclarativeBar3DSeries::handleMultiHighlightGradientUpdate()
{
if (m_multiHighlightGradient)
setSeriesGradient(this, *m_multiHighlightGradient, GradientTypeMulti);
}
void DeclarativeBar3DSeries::handleRowColorUpdate()
{
int colorCount = m_rowColors.size();
int changed = 0;
DeclarativeColor *color = qobject_cast<DeclarativeColor*>(QObject::sender());
for (int i = 0; i < colorCount; i++) {
if (color == m_rowColors.at(i)) {
changed = i;
break;
}
}
QList<QColor> list = QBar3DSeries::rowColors();
list[changed] = m_rowColors.at(changed)->color();
QBar3DSeries::setRowColors(list);
}
void DeclarativeBar3DSeries::addColor(DeclarativeColor *color)
{
if (!color) {
qWarning("Color is invalid, use ThemeColor");
return;
}
clearDummyColors();
m_rowColors.append(color);
connect(color, &DeclarativeColor::colorChanged, this,
&DeclarativeBar3DSeries::handleRowColorUpdate);
QList<QColor> list = QBar3DSeries::rowColors();
list.append(color->color());
QBar3DSeries::setRowColors(list);
}
QList<DeclarativeColor *> DeclarativeBar3DSeries::colorList()
{
if (m_rowColors.isEmpty()) {
m_dummyColors = true;
const QList<QColor> list = QBar3DSeries::rowColors();
for (const QColor &item : list) {
DeclarativeColor *color = new DeclarativeColor(this);
color->setColor(item);
m_rowColors.append(color);
connect(color, &DeclarativeColor::colorChanged, this,
&DeclarativeBar3DSeries::handleRowColorUpdate);
}
}
return m_rowColors;
}
void DeclarativeBar3DSeries::clearColors()
{
clearDummyColors();
for (const auto color : std::as_const(m_rowColors))
disconnect(color, 0, this, 0);
m_rowColors.clear();
QBar3DSeries::setRowColors(QList<QColor>());
}
void DeclarativeBar3DSeries::clearDummyColors()
{
if (m_dummyColors) {
qDeleteAll(m_rowColors);
m_rowColors.clear();
m_dummyColors = false;
}
}
DeclarativeScatter3DSeries::DeclarativeScatter3DSeries(QObject *parent)
: QScatter3DSeries(parent),
m_baseGradient(0),
m_singleHighlightGradient(0),
m_multiHighlightGradient(0)
{
}
DeclarativeScatter3DSeries::~DeclarativeScatter3DSeries()
{
}
QQmlListProperty<QObject> DeclarativeScatter3DSeries::seriesChildren()
{
return QQmlListProperty<QObject>(this, this, &DeclarativeScatter3DSeries::appendSeriesChildren
, 0, 0, 0);
}
void DeclarativeScatter3DSeries::appendSeriesChildren(QQmlListProperty<QObject> *list,
QObject *element)
{
QScatterDataProxy *proxy = qobject_cast<QScatterDataProxy *>(element);
if (proxy)
reinterpret_cast<DeclarativeScatter3DSeries *>(list->data)->setDataProxy(proxy);
}
void DeclarativeScatter3DSeries::setBaseGradient(ColorGradient *gradient)
{
connectSeriesGradient(this, gradient, GradientTypeBase, &m_baseGradient);
}
ColorGradient *DeclarativeScatter3DSeries::baseGradient() const
{
return m_baseGradient;
}
void DeclarativeScatter3DSeries::setSingleHighlightGradient(ColorGradient *gradient)
{
connectSeriesGradient(this, gradient, GradientTypeSingle, &m_singleHighlightGradient);
}
ColorGradient *DeclarativeScatter3DSeries::singleHighlightGradient() const
{
return m_singleHighlightGradient;
}
void DeclarativeScatter3DSeries::setMultiHighlightGradient(ColorGradient *gradient)
{
connectSeriesGradient(this, gradient, GradientTypeMulti, &m_multiHighlightGradient);
}
ColorGradient *DeclarativeScatter3DSeries::multiHighlightGradient() const
{
return m_multiHighlightGradient;
}
int DeclarativeScatter3DSeries::invalidSelectionIndex() const
{
return QScatter3DSeries::invalidSelectionIndex();
}
void DeclarativeScatter3DSeries::handleBaseGradientUpdate()
{
if (m_baseGradient)
setSeriesGradient(this, *m_baseGradient, GradientTypeBase);
}
void DeclarativeScatter3DSeries::handleSingleHighlightGradientUpdate()
{
if (m_singleHighlightGradient)
setSeriesGradient(this, *m_singleHighlightGradient, GradientTypeSingle);
}
void DeclarativeScatter3DSeries::handleMultiHighlightGradientUpdate()
{
if (m_multiHighlightGradient)
setSeriesGradient(this, *m_multiHighlightGradient, GradientTypeMulti);
}
DeclarativeSurface3DSeries::DeclarativeSurface3DSeries(QObject *parent)
: QSurface3DSeries(parent),
m_baseGradient(0),
m_singleHighlightGradient(0),
m_multiHighlightGradient(0)
{
QObject::connect(this, &QSurface3DSeries::selectedPointChanged, this,
&DeclarativeSurface3DSeries::selectedPointChanged);
}
DeclarativeSurface3DSeries::~DeclarativeSurface3DSeries()
{
}
void DeclarativeSurface3DSeries::setSelectedPoint(const QPointF &position)
{
QSurface3DSeries::setSelectedPoint(position.toPoint());
}
QPointF DeclarativeSurface3DSeries::selectedPoint() const
{
return QPointF(QSurface3DSeries::selectedPoint());
}
QPointF DeclarativeSurface3DSeries::invalidSelectionPosition() const
{
return QPointF(QSurface3DSeries::invalidSelectionPosition());
}
QQmlListProperty<QObject> DeclarativeSurface3DSeries::seriesChildren()
{
return QQmlListProperty<QObject>(this, this, &DeclarativeSurface3DSeries::appendSeriesChildren
, 0, 0, 0);
}
void DeclarativeSurface3DSeries::appendSeriesChildren(QQmlListProperty<QObject> *list,
QObject *element)
{
QSurfaceDataProxy *proxy = qobject_cast<QSurfaceDataProxy *>(element);
if (proxy)
reinterpret_cast<DeclarativeSurface3DSeries *>(list->data)->setDataProxy(proxy);
}
void DeclarativeSurface3DSeries::setBaseGradient(ColorGradient *gradient)
{
connectSeriesGradient(this, gradient, GradientTypeBase, &m_baseGradient);
}
ColorGradient *DeclarativeSurface3DSeries::baseGradient() const
{
return m_baseGradient;
}
void DeclarativeSurface3DSeries::setSingleHighlightGradient(ColorGradient *gradient)
{
connectSeriesGradient(this, gradient, GradientTypeSingle, &m_singleHighlightGradient);
}
ColorGradient *DeclarativeSurface3DSeries::singleHighlightGradient() const
{
return m_singleHighlightGradient;
}
void DeclarativeSurface3DSeries::setMultiHighlightGradient(ColorGradient *gradient)
{
connectSeriesGradient(this, gradient, GradientTypeMulti, &m_multiHighlightGradient);
}
ColorGradient *DeclarativeSurface3DSeries::multiHighlightGradient() const
{
return m_multiHighlightGradient;
}
void DeclarativeSurface3DSeries::handleBaseGradientUpdate()
{
if (m_baseGradient)
setSeriesGradient(this, *m_baseGradient, GradientTypeBase);
}
void DeclarativeSurface3DSeries::handleSingleHighlightGradientUpdate()
{
if (m_singleHighlightGradient)
setSeriesGradient(this, *m_singleHighlightGradient, GradientTypeSingle);
}
void DeclarativeSurface3DSeries::handleMultiHighlightGradientUpdate()
{
if (m_multiHighlightGradient)
setSeriesGradient(this, *m_multiHighlightGradient, GradientTypeMulti);
}
QT_END_NAMESPACE