diff --git a/src/elevatedrectangle.cpp b/src/elevatedrectangle.cpp index 243069d4..0df9b475 100644 --- a/src/elevatedrectangle.cpp +++ b/src/elevatedrectangle.cpp @@ -1,162 +1,162 @@ /* * Copyright 2020 Arjen Hiemstra * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) version 3, or any * later version accepted by the membership of KDE e.V. (or its * successor approved by the membership of KDE e.V.), which shall * act as a proxy defined in Section 6 of version 3 of the license. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #include "elevatedrectangle.h" #include "scenegraph/elevatedrectanglenode.h" class ElevatedRectangle::Private { public: qreal elevation = 0.0; qreal radius = 0.0; qreal xOffset = 0.0; qreal yOffset = 0.0; QColor color = Qt::white; QColor shadowColor = Qt::black; }; ElevatedRectangle::ElevatedRectangle(QQuickItem *parentItem) : QQuickItem(parentItem), d(new Private) { setFlag(QQuickItem::ItemHasContents, true); } ElevatedRectangle::~ElevatedRectangle() { } qreal ElevatedRectangle::elevation() const { return d->elevation; } void ElevatedRectangle::setElevation(qreal newElevation) { if (newElevation == d->elevation) { return; } d->elevation = newElevation; update(); Q_EMIT elevationChanged(); } qreal ElevatedRectangle::radius() const { return d->radius; } void ElevatedRectangle::setRadius(qreal newRadius) { newRadius = std::min(newRadius, std::min(width(), height())); if (newRadius == d->radius) { return; } d->radius = newRadius; update(); Q_EMIT radiusChanged(); } qreal ElevatedRectangle::xOffset() const { return d->xOffset; } void ElevatedRectangle::setXOffset(qreal newXOffset) { if (newXOffset == d->xOffset) { return; } d->xOffset = newXOffset; update(); Q_EMIT xOffsetChanged(); } qreal ElevatedRectangle::yOffset() const { return d->yOffset; } void ElevatedRectangle::setYOffset(qreal newYOffset) { if (newYOffset == d->yOffset) { return; } d->yOffset = newYOffset; update(); Q_EMIT yOffsetChanged(); } QColor ElevatedRectangle::color() const { return d->color; } void ElevatedRectangle::setColor(const QColor & newColor) { if (newColor == d->color) { return; } d->color = newColor; update(); Q_EMIT colorChanged(); } QColor ElevatedRectangle::shadowColor() const { return d->shadowColor; } void ElevatedRectangle::setShadowColor(const QColor &newShadowColor) { if (newShadowColor == d->shadowColor) { return; } d->shadowColor = newShadowColor; update(); Q_EMIT shadowColorChanged(); } QSGNode *ElevatedRectangle::updatePaintNode(QSGNode *node, QQuickItem::UpdatePaintNodeData *data) { Q_UNUSED(data); if (!node) { node = new ElevatedRectangleNode; } auto elevatedNode = static_cast(node); - elevatedNode->setRect(boundingRect().adjusted(-d->elevation, -d->elevation, d->elevation, d->elevation)); + elevatedNode->setRect(boundingRect()); elevatedNode->setElevation(d->elevation); elevatedNode->setRadius(d->radius); elevatedNode->setOffset(QVector2D{float(d->xOffset), float(d->yOffset)}); elevatedNode->setColor(d->color); elevatedNode->setShadowColor(d->shadowColor); elevatedNode->updateGeometry(); return elevatedNode; } diff --git a/src/scenegraph/elevatedrectanglenode.cpp b/src/scenegraph/elevatedrectanglenode.cpp index 252d5d6d..1fe968fa 100644 --- a/src/scenegraph/elevatedrectanglenode.cpp +++ b/src/scenegraph/elevatedrectanglenode.cpp @@ -1,134 +1,126 @@ /* * Copyright 2020 Arjen Hiemstra * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) version 3, or any * later version accepted by the membership of KDE e.V. (or its * successor approved by the membership of KDE e.V.), which shall * act as a proxy defined in Section 6 of version 3 of the license. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see */ #include "elevatedrectanglenode.h" #include "elevatedrectanglematerial.h" #include ElevatedRectangleNode::ElevatedRectangleNode(const QRectF& rect) { m_geometry = new QSGGeometry{QSGGeometry::defaultAttributes_TexturedPoint2D(), 4}; setGeometry(m_geometry); setRect(rect); m_material = new ElevatedRectangleMaterial{}; setMaterial(m_material); setFlags(QSGNode::OwnsGeometry | QSGNode::OwnsMaterial); } void ElevatedRectangleNode::setRect(const QRectF& rect) { if (rect == m_rect) { return; } m_rect = rect; QVector2D newAspect{1.0, 1.0}; if (m_rect.width() >= m_rect.height()) { newAspect.setX(m_rect.width() / m_rect.height()); } else { newAspect.setY(m_rect.height() / m_rect.width()); } if (m_material->aspect != newAspect) { - qDebug() << newAspect; m_material->aspect = newAspect; markDirty(QSGNode::DirtyMaterial); m_aspect = newAspect; } } void ElevatedRectangleNode::setElevation(qreal elevation) { auto minDimension = std::min(m_rect.width(), m_rect.height()); float uniformElevation = (elevation / minDimension) * 2.0; if (!qFuzzyCompare(m_material->elevation, uniformElevation)) { m_material->elevation = uniformElevation; markDirty(QSGNode::DirtyMaterial); m_elevation = elevation; } } void ElevatedRectangleNode::setRadius(qreal radius) { auto minDimension = std::min(m_rect.width(), m_rect.height()); float uniformRadius = radius * 2.0 / minDimension; if (!qFuzzyCompare(m_material->radius, uniformRadius)) { m_material->radius = uniformRadius; markDirty(QSGNode::DirtyMaterial); m_radius = radius; } } void ElevatedRectangleNode::setColor(const QColor &color) { if (m_material->color != color) { m_material->color = color; markDirty(QSGNode::DirtyMaterial); } } void ElevatedRectangleNode::setShadowColor(const QColor& color) { if (m_material->shadowColor != color) { m_material->shadowColor = color; markDirty(QSGNode::DirtyMaterial); } } void ElevatedRectangleNode::setOffset(const QVector2D& offset) { auto minDimension = std::min(m_rect.width(), m_rect.height()); auto uniformOffset = offset * 2.0 / minDimension; if (m_material->offset != uniformOffset) { m_material->offset = uniformOffset; markDirty(QSGNode::DirtyMaterial); m_offset = offset; } } void ElevatedRectangleNode::updateGeometry() { -// auto rect = m_rect.adjusted(-m_elevation, -m_elevation, m_elevation, m_elevation); - auto rect = m_rect; + auto rect = m_rect.adjusted(-m_elevation * m_aspect.x(), -m_elevation * m_aspect.y(), + m_elevation * m_aspect.x(), m_elevation * m_aspect.y()); - if (m_offset.x() < 0.0f) { - rect.setLeft(rect.left() + m_offset.x()); - } else { - rect.setRight(rect.right() + m_offset.x()); - } + auto offsetLength = m_offset.length(); - if (m_offset.y() < 0.0f) { - rect.setTop(rect.top() + m_offset.y()); - } else { - rect.setBottom(rect.bottom() + m_offset.y()); - } + rect = rect.adjusted(-offsetLength * m_aspect.x(), -offsetLength * m_aspect.y(), + offsetLength * m_aspect.x(), offsetLength * m_aspect.y()); - QSGGeometry::updateTexturedRectGeometry(m_geometry, rect, QRectF{0, 0, 1, 1}); + QSGGeometry::updateTexturedRectGeometry(m_geometry, rect, QRectF{0.0, 0.0, 1.0, 1.0}); markDirty(QSGNode::DirtyGeometry); }