Qt Reference Documentation

sortingbox.cpp Example File

widgets/tooltips/sortingbox.cpp
 /****************************************************************************
 **
 ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
 ** Contact: http://www.qt-project.org/legal
 **
 ** This file is part of the examples of the Qt Toolkit.
 **
 ** $QT_BEGIN_LICENSE:BSD$
 ** 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 Digia Plc and its Subsidiary(-ies) 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 <QtGui>

 #include <stdlib.h>

 #include "sortingbox.h"

 SortingBox::SortingBox()
 {
     setMouseTracking(true);
     setBackgroundRole(QPalette::Base);

     itemInMotion = 0;

     newCircleButton = createToolButton(tr("New Circle"),
                                        QIcon(":/images/circle.png"),
                                        SLOT(createNewCircle()));

     newSquareButton = createToolButton(tr("New Square"),
                                        QIcon(":/images/square.png"),
                                        SLOT(createNewSquare()));

     newTriangleButton = createToolButton(tr("New Triangle"),
                                          QIcon(":/images/triangle.png"),
                                          SLOT(createNewTriangle()));

     circlePath.addEllipse(QRect(0, 0, 100, 100));
     squarePath.addRect(QRect(0, 0, 100, 100));

     qreal x = trianglePath.currentPosition().x();
     qreal y = trianglePath.currentPosition().y();
     trianglePath.moveTo(x + 120 / 2, y);
     trianglePath.lineTo(0, 100);
     trianglePath.lineTo(120, 100);
     trianglePath.lineTo(x + 120 / 2, y);

     setWindowTitle(tr("Tool Tips"));
     resize(500, 300);

     createShapeItem(circlePath, tr("Circle"), initialItemPosition(circlePath),
                     initialItemColor());
     createShapeItem(squarePath, tr("Square"), initialItemPosition(squarePath),
                     initialItemColor());
     createShapeItem(trianglePath, tr("Triangle"),
                     initialItemPosition(trianglePath), initialItemColor());
 }

 bool SortingBox::event(QEvent *event)
 {
     if (event->type() == QEvent::ToolTip) {
         QHelpEvent *helpEvent = static_cast<QHelpEvent *>(event);
         int index = itemAt(helpEvent->pos());
         if (index != -1) {
             QToolTip::showText(helpEvent->globalPos(), shapeItems[index].toolTip());
         } else {
             QToolTip::hideText();
             event->ignore();
         }

         return true;
     }
     return QWidget::event(event);
 }

 void SortingBox::resizeEvent(QResizeEvent * /* event */)
 {
     int margin = style()->pixelMetric(QStyle::PM_DefaultTopLevelMargin);
     int x = width() - margin;
     int y = height() - margin;

     y = updateButtonGeometry(newCircleButton, x, y);
     y = updateButtonGeometry(newSquareButton, x, y);
     updateButtonGeometry(newTriangleButton, x, y);
 }

 void SortingBox::paintEvent(QPaintEvent * /* event */)
 {
     QPainter painter(this);
     painter.setRenderHint(QPainter::Antialiasing);
     foreach (ShapeItem shapeItem, shapeItems) {
         painter.translate(shapeItem.position());
         painter.setBrush(shapeItem.color());
         painter.drawPath(shapeItem.path());
         painter.translate(-shapeItem.position());
     }
 }

 void SortingBox::mousePressEvent(QMouseEvent *event)
 {
     if (event->button() == Qt::LeftButton) {
         int index = itemAt(event->pos());
         if (index != -1) {
             itemInMotion = &shapeItems[index];
             previousPosition = event->pos();
             shapeItems.move(index, shapeItems.size() - 1);
             update();
         }
     }
 }

 void SortingBox::mouseMoveEvent(QMouseEvent *event)
 {
     if ((event->buttons() & Qt::LeftButton) && itemInMotion)
         moveItemTo(event->pos());
 }

 void SortingBox::mouseReleaseEvent(QMouseEvent *event)
 {
     if (event->button() == Qt::LeftButton && itemInMotion) {
         moveItemTo(event->pos());
         itemInMotion = 0;
     }
 }

 void SortingBox::createNewCircle()
 {
     static int count = 1;
     createShapeItem(circlePath, tr("Circle <%1>").arg(++count),
                     randomItemPosition(), randomItemColor());
 }

 void SortingBox::createNewSquare()
 {
     static int count = 1;
     createShapeItem(squarePath, tr("Square <%1>").arg(++count),
                     randomItemPosition(), randomItemColor());
 }

 void SortingBox::createNewTriangle()
 {
     static int count = 1;
     createShapeItem(trianglePath, tr("Triangle <%1>").arg(++count),
                     randomItemPosition(), randomItemColor());
 }

 int SortingBox::itemAt(const QPoint &pos)
 {
     for (int i = shapeItems.size() - 1; i >= 0; --i) {
         const ShapeItem &item = shapeItems[i];
         if (item.path().contains(pos - item.position()))
             return i;
     }
     return -1;
 }

 void SortingBox::moveItemTo(const QPoint &pos)
 {
     QPoint offset = pos - previousPosition;
     itemInMotion->setPosition(itemInMotion->position() + offset);
     previousPosition = pos;
     update();
 }

 int SortingBox::updateButtonGeometry(QToolButton *button, int x, int y)
 {
     QSize size = button->sizeHint();
     button->setGeometry(x - size.rwidth(), y - size.rheight(),
                         size.rwidth(), size.rheight());

     return y - size.rheight()
            - style()->pixelMetric(QStyle::PM_DefaultLayoutSpacing);
 }

 void SortingBox::createShapeItem(const QPainterPath &path,
                                  const QString &toolTip, const QPoint &pos,
                                  const QColor &color)
 {
     ShapeItem shapeItem;
     shapeItem.setPath(path);
     shapeItem.setToolTip(toolTip);
     shapeItem.setPosition(pos);
     shapeItem.setColor(color);
     shapeItems.append(shapeItem);
     update();
 }

 QToolButton *SortingBox::createToolButton(const QString &toolTip,
                                           const QIcon &icon, const char *member)
 {
     QToolButton *button = new QToolButton(this);
     button->setToolTip(toolTip);
     button->setIcon(icon);
     button->setIconSize(QSize(32, 32));
     connect(button, SIGNAL(clicked()), this, member);

     return button;
 }

 QPoint SortingBox::initialItemPosition(const QPainterPath &path)
 {
     int x;
     int y = (height() - (int)path.controlPointRect().height()) / 2;
     if (shapeItems.size() == 0)
         x = ((3 * width()) / 2 - (int)path.controlPointRect().width()) / 2;
     else
         x = (width() / shapeItems.size()
              - (int)path.controlPointRect().width()) / 2;

     return QPoint(x, y);
 }

 QPoint SortingBox::randomItemPosition()
 {
     return QPoint(qrand() % (width() - 120), qrand() % (height() - 120));
 }

 QColor SortingBox::initialItemColor()
 {
     return QColor::fromHsv(((shapeItems.size() + 1) * 85) % 256, 255, 190);
 }

 QColor SortingBox::randomItemColor()
 {
     return QColor::fromHsv(qrand() % 256, 255, 190);
 }