Qt Reference Documentation

# sortingbox.cpp Example File

widgets/tooltips/sortingbox.cpp

     /****************************************************************************
     **
     ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
     ** All rights reserved.
     ** Contact: Nokia Corporation (qt-info@nokia.com)
     **
     ** 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 Nokia Corporation 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);
     }