File indexing completed on 2024-04-28 04:32:07

0001 /*
0002  * Copyright (C) 2015 by Stephen Allewell
0003  * steve.allewell@gmail.com
0004  *
0005  * This program is free software; you can redistribute it and/or modify
0006  * it under the terms of the GNU General Public License as published by
0007  * the Free Software Foundation; either version 2 of the License, or
0008  * (at your option) any later version.
0009  */
0010 
0011 /** @file
0012  * This file defines an extension to a QLabel that scales the associated QPixmap
0013  * to maintain the aspect ratio when scaling to fill the extents of the QLabel
0014  * area.
0015  */
0016 
0017 #ifndef ScaledPixmapLabel_H
0018 #define ScaledPixmapLabel_H
0019 
0020 // Qt includes
0021 #include <QLabel>
0022 #include <QPixmap>
0023 
0024 // Forward declaration of classes
0025 class QMouseEvent;
0026 
0027 /**
0028  * This class extends QLabel to scale the associated QPixmap to fill the QLabel
0029  * area whilst maintaining the aspect ratio of the pixmap.
0030  */
0031 class ScaledPixmapLabel : public QLabel
0032 {
0033     Q_OBJECT
0034 
0035 public:
0036     /**
0037      * Constructor to initialise the class as a child of the parent.
0038      *
0039      * @param parent is a pointer to the parent QWidget
0040      */
0041     explicit ScaledPixmapLabel(QWidget *parent);
0042 
0043     /**
0044      * This overrides the base class method to calculate the height required
0045      * to maintain the aspect ratio for the specified width.
0046      *
0047      * @param width is the required width
0048      *
0049      * @return an int representing the height required
0050      */
0051     virtual int heightForWidth(int width) const Q_DECL_OVERRIDE;
0052 
0053     /**
0054      * This overrides the base class method to calculate the size of the widget
0055      * required to fill the parent window and maintain the aspect ratio.
0056      *
0057      * @return a QSize representing the width and height
0058      */
0059     virtual QSize sizeHint() const Q_DECL_OVERRIDE;
0060 
0061     /**
0062      * Calculate the size and position occupied by the scaled pixmap.
0063      *
0064      * @return a QRect representing the area occupied by the pixmap
0065      */
0066     QRect pixmapRect() const;
0067 
0068 signals:
0069     /**
0070      * Emit a signal to notify a change in the crop area.
0071      * The value is scaled to relate to the modified image not the size of the QLabel.
0072      * A QRectF is used for accuracy to prevent rounding error with the various scaling
0073      * that occurs.
0074      *
0075      * @param rect a QRect defining the area of the image being cropped
0076      */
0077     void imageCropped(const QRectF &rectF);
0078 
0079 public slots:
0080     /**
0081      * Set the pixmap of the QLabel to a scaled version of the supplied pixmap.
0082      * The supplied pixmap is stored within the class to be reused when resizing.
0083      * This method hides the QLabel version which is then called from this one.
0084      *
0085      * @param pixmap a const reference to the QPixmap to be assigned to the QLabel
0086      */
0087     void setPixmap(const QPixmap &pixmap);
0088 
0089     /**
0090      * Enable cropping of the image
0091      *
0092      * @param checked is a bool enabling cropping of the image
0093      */
0094     void setCropping(bool checked);
0095 
0096 protected:
0097     /**
0098      * This overrides the base class method to resize the pixmap maintaining the
0099      * aspect ratio.  The widget has been resized at this point and the event
0100      * parameter is not used to determine the new size of the pixmap as the size
0101      * is taken from the widget size.
0102      *
0103      * @param event is a pointer to a QResizeEvent
0104      */
0105     virtual void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE;
0106 
0107     /**
0108      * Override the paint event to allow drawing of a crop rectangle based on the
0109      * value of m_crop.
0110      *
0111      * @param event is a pointer to a QPaintEvent
0112      */
0113     virtual void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE;
0114 
0115     /**
0116      * Override the mousePressEvent to begin a crop operation of the image
0117      * defining the start position.
0118      *
0119      * @param event is a pointer to the QMouseEvent
0120      */
0121     virtual void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
0122 
0123     /**
0124      * Override the mouseMoveEvent to drag a selection rectangle across the
0125      * image to define the crop area.
0126      *
0127      * @param event is a pointer to the QMouseEvent
0128      */
0129     virtual void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
0130 
0131     /**
0132      * Override the mouseReleaseEvent to end the selection of a crop area.
0133      *
0134      * @param event is a pointer to the QMouseEvent
0135      */
0136     virtual void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
0137 
0138     /**
0139      * When the mouse leaves the widget, update the view so that the
0140      * guides are removed.
0141      *
0142      * @param event is a pointer to the QEvent
0143      */
0144     virtual void leaveEvent(QEvent *event) Q_DECL_OVERRIDE;
0145 
0146 private:
0147     QPixmap m_pixmap; /**< copy of the pixmap which is scaled to fill the label */
0148     bool m_cropping; /**< true if cropping is enabled */
0149     QPoint m_start; /**< start position of the crop rectangle */
0150     QPoint m_end; /**< end position of the crop rectangle */
0151     QRect m_crop; /**< rectangle defining the crop area in normalized coordinates */
0152 };
0153 
0154 #endif // ScaledPixmapLabel_H