| /**************************************************************************** |
| ** |
| ** Copyright (C) 2016 The Qt Company Ltd. |
| ** Contact: https://www.qt.io/licensing/ |
| ** |
| ** This file is part of the examples of the Qt Toolkit. |
| ** |
| ** $QT_BEGIN_LICENSE:BSD$ |
| ** 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. |
| ** |
| ** BSD License Usage |
| ** Alternatively, you may use this file under the terms of the BSD license |
| ** as follows: |
| ** |
| ** "Redistribution and use in source and binary forms, with or without |
| ** modification, are permitted provided that the following conditions are |
| ** met: |
| ** * Redistributions of source code must retain the above copyright |
| ** notice, this list of conditions and the following disclaimer. |
| ** * Redistributions in binary form must reproduce the above copyright |
| ** notice, this list of conditions and the following disclaimer in |
| ** the documentation and/or other materials provided with the |
| ** distribution. |
| ** * Neither the name of The Qt Company Ltd nor the names of its |
| ** contributors may be used to endorse or promote products derived |
| ** from this software without specific prior written permission. |
| ** |
| ** |
| ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." |
| ** |
| ** $QT_END_LICENSE$ |
| ** |
| ****************************************************************************/ |
| |
| #include <QtWidgets> |
| |
| #include "bubble.h" |
| |
| Bubble::Bubble(const QPointF &position, qreal radius, const QPointF &velocity) |
| : position(position), vel(velocity), radius(radius) |
| { |
| innerColor = randomColor(); |
| outerColor = randomColor(); |
| cache = 0; |
| updateBrush(); |
| } |
| |
| //! [0] |
| void Bubble::updateCache() |
| { |
| if (cache) |
| delete cache; |
| cache = new QImage(qRound(radius * 2 + 2), qRound(radius * 2 + 2), QImage::Format_ARGB32_Premultiplied); |
| cache->fill(0x00000000); |
| QPainter p(cache); |
| p.setRenderHint(QPainter::Antialiasing); |
| QPen pen(Qt::white); |
| pen.setWidth(2); |
| p.setPen(pen); |
| p.setBrush(brush); |
| p.drawEllipse(1, 1, int(2*radius), int(2*radius)); |
| } |
| //! [0] |
| |
| Bubble::~Bubble() |
| { |
| if (cache) |
| delete cache; |
| } |
| |
| void Bubble::updateBrush() |
| { |
| QRadialGradient gradient(QPointF(radius, radius), radius, |
| QPointF(radius*0.5, radius*0.5)); |
| |
| gradient.setColorAt(0, QColor(255, 255, 255, 255)); |
| gradient.setColorAt(0.25, innerColor); |
| gradient.setColorAt(1, outerColor); |
| brush = QBrush(gradient); |
| updateCache(); |
| } |
| |
| //! [1] |
| void Bubble::drawBubble(QPainter *painter) |
| { |
| painter->save(); |
| painter->translate(position.x() - radius, position.y() - radius); |
| painter->setOpacity(0.8); |
| painter->drawImage(0, 0, *cache); |
| painter->restore(); |
| } |
| //! [1] |
| |
| QColor Bubble::randomColor() |
| { |
| int red = int(185 + QRandomGenerator::global()->bounded(70)); |
| int green = int(185 + QRandomGenerator::global()->bounded(70)); |
| int blue = int(205 + QRandomGenerator::global()->bounded(50)); |
| int alpha = int(91 + QRandomGenerator::global()->bounded(100)); |
| |
| return QColor(red, green, blue, alpha); |
| } |
| |
| void Bubble::move(const QRect &bbox) |
| { |
| position += vel; |
| qreal leftOverflow = position.x() - radius - bbox.left(); |
| qreal rightOverflow = position.x() + radius - bbox.right(); |
| qreal topOverflow = position.y() - radius - bbox.top(); |
| qreal bottomOverflow = position.y() + radius - bbox.bottom(); |
| |
| if (leftOverflow < 0.0) { |
| position.setX(position.x() - 2 * leftOverflow); |
| vel.setX(-vel.x()); |
| } else if (rightOverflow > 0.0) { |
| position.setX(position.x() - 2 * rightOverflow); |
| vel.setX(-vel.x()); |
| } |
| |
| if (topOverflow < 0.0) { |
| position.setY(position.y() - 2 * topOverflow); |
| vel.setY(-vel.y()); |
| } else if (bottomOverflow > 0.0) { |
| position.setY(position.y() - 2 * bottomOverflow); |
| vel.setY(-vel.y()); |
| } |
| } |
| |
| QRectF Bubble::rect() |
| { |
| return QRectF(position.x() - radius, position.y() - radius, |
| 2 * radius, 2 * radius); |
| } |