File indexing completed on 2024-05-19 05:42:16

0001 // ct_lvtqtc_graphicsrectitem.cpp                                      -*-C++-*-
0002 
0003 /*
0004 // Copyright 2023 Codethink Ltd <codethink@codethink.co.uk>
0005 // SPDX-License-Identifier: Apache-2.0
0006 //
0007 // Licensed under the Apache License, Version 2.0 (the "License");
0008 // you may not use this file except in compliance with the License.
0009 // You may obtain a copy of the License at
0010 //
0011 //     http://www.apache.org/licenses/LICENSE-2.0
0012 //
0013 // Unless required by applicable law or agreed to in writing, software
0014 // distributed under the License is distributed on an "AS IS" BASIS,
0015 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0016 // See the License for the specific language governing permissions and
0017 // limitations under the License.
0018 */
0019 
0020 #include <ct_lvtqtc_graphicsrectitem.h>
0021 
0022 #include <ct_lvtqtc_util.h>
0023 
0024 #include <QBrush>
0025 #include <QColor>
0026 #include <QDebug>
0027 #include <QElapsedTimer>
0028 #include <QGraphicsScene>
0029 #include <QGraphicsSceneMouseEvent>
0030 #include <QPainter>
0031 #include <QPen>
0032 #include <QStyleOptionGraphicsItem>
0033 #include <QVector2D>
0034 
0035 namespace {
0036 
0037 constexpr int OUTLINE_ADJUSTMENT = 3;
0038 // the amount we adjust each successive outline rectangle
0039 } // namespace
0040 
0041 namespace Codethink::lvtqtc {
0042 
0043 struct GraphicsRectItem::Private {
0044     qreal xRadius = 5;
0045     qreal yRadius = 5;
0046     int numOutlines = 1;
0047     QPainterPath shapeRect;
0048 };
0049 
0050 GraphicsRectItem::GraphicsRectItem(QGraphicsItem *parent):
0051     QGraphicsRectItem(parent), d(std::make_unique<GraphicsRectItem::Private>())
0052 {
0053 }
0054 
0055 GraphicsRectItem::~GraphicsRectItem() = default;
0056 
0057 void GraphicsRectItem::setRoundRadius(qreal radius)
0058 {
0059     d->xRadius = radius;
0060     d->yRadius = radius;
0061     update();
0062 }
0063 
0064 void GraphicsRectItem::setRectangle(const QRectF& r)
0065 {
0066     if (rect() == r) {
0067         return;
0068     }
0069 
0070     d->shapeRect = QPainterPath();
0071     d->shapeRect.addRoundedRect(r, d->xRadius, d->yRadius);
0072     setRect(r);
0073 
0074     Q_EMIT rectangleChanged();
0075 }
0076 
0077 qreal GraphicsRectItem::roundRadius() const
0078 {
0079     return d->xRadius;
0080     // if we are treating both radius as the same, then just return one.
0081 }
0082 
0083 void GraphicsRectItem::setXRadius(qreal radius)
0084 {
0085     d->xRadius = radius;
0086     update();
0087 }
0088 
0089 void GraphicsRectItem::setYRadius(qreal radius)
0090 {
0091     d->yRadius = radius;
0092     update();
0093 }
0094 
0095 void GraphicsRectItem::setNumOutlines(int numOutlines)
0096 {
0097     d->numOutlines = numOutlines;
0098     update();
0099 }
0100 
0101 void GraphicsRectItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
0102 {
0103     Q_UNUSED(option);
0104     Q_UNUSED(widget);
0105 
0106     painter->save();
0107     painter->setPen(pen());
0108     painter->setBrush(brush());
0109 
0110     for (int i = 0; i < d->numOutlines; i++) {
0111         const int adj = OUTLINE_ADJUSTMENT * i;
0112         QRectF adjRect = rect().adjusted(adj, adj, -adj, -adj);
0113 
0114         painter->drawRoundedRect(adjRect, d->xRadius, d->yRadius);
0115     }
0116 
0117     if (option->state.testFlag(QStyle::State_Selected)) {
0118         painter->setBrush(Qt::NoBrush);
0119         painter->setPen(QPen(QBrush(QColor(Qt::black)), 1, Qt::PenStyle::DashLine));
0120         painter->drawRect(rect());
0121     }
0122 
0123     painter->restore();
0124 }
0125 
0126 QPainterPath GraphicsRectItem::shape() const
0127 {
0128     return d->shapeRect;
0129 }
0130 
0131 } // end namespace Codethink::lvtqtc