Logo Search packages:      
Sourcecode: palapeli version File versions  Download package

pattern.h

/***************************************************************************
 *   Copyright (C) 2008 Stefan Majewsky <majewsky@gmx.net>
 *
 *   This program is free software; you can redistribute it and/or
 *   modify it under the terms of the GNU General Public
 *   License as published by the Free Software Foundation; either
 *   version 2 of the License, or (at your option) any later version.
 *
 *   This program 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 General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 ***************************************************************************/

#ifndef PALAPELI_PATTERN_H
#define PALAPELI_PATTERN_H

#if defined(MAKE_LIBPALAPELIPATTERN)
 #include "macros.h"
#else
 #include <Palapeli/Macros>
#endif

class QImage;
#include <QtCore/QList>
#include <QtCore/QObject>
class QPointF;
class QRectF;

//TODO: add \since command once we move to kdegames

namespace Palapeli
{

      class PatternPrivate;

      /**
       * \class Pattern pattern.h Palapeli/Pattern
       * \short Slicing implementation in Palapeli pattern plugins.
       *
       * This class is used in a Palapeli pattern plugin to provide the actual slicing implementation. Its configuration is generated by the Palapeli::PatternConfiguration subclass contained in the plugin.
       *
       * To create your sub-class of Palapeli::Pattern, you will need to implement the doSlice function. This function can call the addPiece and addRelation functions to add pieces to the puzzle scene, and add neighbor relations between them. Use the mode function to find out what operation mode has been requested for the doSlice function. The following example illustrates a pattern which splits the base image into two equally sized parts:
       \code
class MyPattern : public Palapeli::Pattern {

//implement public constructor and public virtual destructor here

protected:
      virtual void doSlice(const QImage& image) {
            reportPieceCount(2); //the application has to know the piece count to display progress
            if (mode() == CreatePuzzle)
            {
                  //construct images for the pieces
                  const int pieceWidth = image.width() / 2, pieceHeight = image.height();
                  QImage leftPiece = image.copy(QRect(0, 0, pieceWidth, pieceHeight));
                  QImage rightPiece = image.copy(QRect(pieceWidth, 0, pieceWidth, pieceHeight));
                  //add pieces; define a neighborship relation between them
                  addPiece(leftPiece, QRectF(0, 0, pieceWidth, pieceHeight));
                  addPiece(rightPiece, QRectF(pieceWidth, 0, pieceWidth, pieceHeight));
                  addRelation(0, 1); //0 and 1 are the consecutive indices of the pieces
            }
      };

};
       \endcode
       *
       * \author Stefan Majewsky <majewsky@gmx.net>
       */
00074       class PALAPELIPATTERN_EXPORT Pattern : public QObject
      {
            Q_OBJECT
            public:
                  /**
                   * \enum Mode
                   * \brief Defines operation modes for this pattern.
                   * \sa slice, doSlice
                   */
00083                   enum Mode
                  {
00085                         CreatePuzzle,    ///< perform necessary calculations and create pieces and relations (default)
00086                         SimulateCreation ///< perform necessary calculations (e.g. piece count), but create neither pieces nor relations
                  };

                  /**
                   * \brief Constructs a new pattern object.
                   * This base constructor is currently unused; you should implement it to get configuration values from your Palapeli::PatternConfiguration object.
                   */
                  Pattern();
                  /**
                   * \brief Destructor.
                   */
                  virtual ~Pattern();

                  /**
                   * \internal
                   * The Palapeli game engine will call this function if a game is loaded from the storage, in order to give the previous piece positions to the pattern. The base class will handle this process automatically as you create the pieces.
                   */
                  void loadPiecePositions(const QList<QPointF>& points);
                  /**
                   * Indicates which operation mode has been requested for this pattern.
                   * \sa slice, doSlice
                   */
                  Mode mode() const;
                  /**
                   * \internal
                   * (For the Palapeli game engine.) Returns the calculated number of pieces to generate.
                   */
                  int pieceCount() const;
                  /**
                   * \internal
                   * The Palapeli game engine will use this function to indicate the operation mode for this pattern.
                   */
                  void setMode(Mode mode);
                  /**
                   * \internal
                   * The Palapeli game engine will use this function to indicate how big the scene is (in multiples of the image size). The base class will handle this information automatically while you create the pieces.
                   */
                  void setSceneSizeFactor(qreal factor);
                  /**
                   * \internal
                   * The Palapeli game engine will call this function to create pieces from a given \a image. You will not need this function, but you will need to implement the actual slicing in the doSlice function.
                   * \sa doSlice
                   */
                  void slice(const QImage& image);
            protected:
                  /**
                   * \brief Adds a piece to the puzzle scene.
                   * Internally, the piece is assigned a consecutive index (0 for the first piece, 1 for the second piece, and so on) which has to be used when defining relations between the pieces.
                   * \param image the visible image (may contain transparent areas to gain a non-rectangular piece shape)
                   * \param positionInImage the bounding box of the piece (or more precisely, the bounding box of the \a image, including any transparent areas!)
                   */
                  void addPiece(const QImage& image, const QRectF& positionInImage);
                  /**
                   * \brief Adds a piece to the puzzle scene.
                   * \overload
                   * This overload adds the possibility to pass a \a mask which will define a shape to be cut out from the given \a baseImage. This is useful because some environments seem to have problems with image composition in non-GUI threads.
                   */
                  void addPiece(const QImage& baseImage, const QImage& mask, const QRectF& positionInImage);
                  /**
                   * \brief Adds a neighbor relation between two pieces.
                   * \param piece1Id the index of the first piece (assigned by order of addPiece operations, starting at zero)
                   * \param piece2Id the index of the second piece
                   * \see addPiece
                   */
                  void addRelation(int piece1Id, int piece2Id);
                  /**
                   * \brief Informs Palapeli about the number of pieces to expect.
                   * Call this from your slicing algorithm to inform Palapeli about the number of pieces to be expected. (This should, of course, be done before any pieces are added to the scene.) The Palapeli game engine will use this information to show a progress bar to the user.
                   */
                  void reportPieceCount(int pieceCount);
                  /**
                   * \brief Provides the slicing algorithm.
                   * This function splits a given image into pieces and defines relations between them. These pieces and relations are used to build the puzzle.
                   * \param image the image to be sliced
                   * \sa addPiece, addRelation, reportPieceCount
                   */
                  virtual void doSlice(const QImage& image) = 0;
            Q_SIGNALS:
                  /// \internal
                  void pieceCountAvailable(int pieceCount);
                  /// \internal
                  void pieceGenerated(const QImage& image, const QRectF& positionInImage, const QPointF& sceneBasePosition);
                  /// \internal
                  void pieceGenerated(const QImage& image, const QImage& mask, const QRectF& positionInImage, const QPointF& sceneBasePosition);
                  /// \internal
                  void allPiecesGenerated();
                  /// \internal
                  void relationGenerated(int piece1Id, int piece2Id);
            private:
                  QPointF generateNextBasePosition(const QRectF& positionInImage);

                  PatternPrivate* const p;
      };
}

#endif // PALAPELI_PATTERN_H

Generated by  Doxygen 1.6.0   Back to index