File indexing completed on 2025-03-09 03:50:37

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2004-12-09
0007  * Description : image selection widget used by ratio crop tool.
0008  *
0009  * SPDX-FileCopyrightText: 2007      by Jaromir Malenko <malenko at email.cz>
0010  * SPDX-FileCopyrightText: 2008      by Roberto Castagnola <roberto dot castagnola at gmail dot com>
0011  * SPDX-FileCopyrightText: 2004-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0012  *
0013  * SPDX-License-Identifier: GPL-2.0-or-later
0014  *
0015  * ============================================================ */
0016 
0017 #ifndef DIGIKAM_EDITOR_RATIO_CROP_WIDGET_H
0018 #define DIGIKAM_EDITOR_RATIO_CROP_WIDGET_H
0019 
0020 // Qt includes
0021 
0022 #include <QWidget>
0023 #include <QRect>
0024 #include <QColor>
0025 
0026 // Local includes
0027 
0028 #include "imageiface.h"
0029 
0030 using namespace Digikam;
0031 
0032 namespace DigikamEditorRatioCropToolPlugin
0033 {
0034 
0035 class RatioCropWidget : public QWidget
0036 {
0037     Q_OBJECT
0038 
0039 public:
0040 
0041     enum RatioAspect               ///< Constrained Aspect Ratio list. See RatioCropWidget::setSelectionAspectRatioType() method for crop-value implementations.
0042     {
0043         RATIOCUSTOM = 0,           ///< Custom aspect ratio.
0044         RATIO01X01,                ///< 1:1
0045         RATIO02x01,                ///< 2:1
0046         RATIO02x03,                ///< 2:3
0047         RATIO03X01,                ///< 3:1
0048         RATIO03X04,                ///< 3:4
0049         RATIO04X01,                ///< 4:1
0050         RATIO04X05,                ///< 4:5
0051         RATIO05x07,                ///< 5:7
0052         RATIO07x10,                ///< 7:10
0053         RATIO08x05,                ///< 8:5
0054         RATIO16x09,                ///< 19:9
0055         RATIODINA0,                ///< DIN A
0056         RATIOGOLDEN,               ///< Golden ratio : 1:1.618
0057         RATIOCURRENT,              ///< Current loaded image aspect ratio
0058         RATIONONE                  ///< No aspect ratio.
0059     };
0060 
0061     enum Orient
0062     {
0063         Landscape = 0,
0064         Portrait
0065     };
0066 
0067     enum CenterType
0068     {
0069         CenterWidth = 0,           ///< Center selection to the center of image width.
0070         CenterHeight,              ///< Center selection to the center of image height.
0071         CenterImage                ///< Center selection to the center of image.
0072     };
0073 
0074     // Proportion : Golden Ratio and Rule of Thirds. More information at this url:
0075     // photoinf.com/General/Robert_Berdan/Composition_and_the_Elements_of_Visual_Design.htm
0076 
0077     enum GuideLineType
0078     {
0079         RulesOfThirds = 0,         ///< Line guides position to 1/3 width and height.
0080         DiagonalMethod,            ///< Diagonal Method to improve composition.
0081         HarmoniousTriangles,       ///< Harmonious Triangle to improve composition.
0082         GoldenMean,                ///< Guides tools using Phi ratio (1.618).
0083         CenterLines,               ///< Line guides position to 1/2 width and height.
0084         GuideNone                  ///< No guide line.
0085     };
0086 
0087 public:
0088 
0089     RatioCropWidget(int width, int height, QWidget* const parent = nullptr);
0090     RatioCropWidget(int width, int height, bool initDrawing, QWidget* const parent = nullptr);
0091     ~RatioCropWidget() override;
0092 
0093     void  setBackgroundColor(const QColor& bg);
0094     void  setCenterSelection(int centerType=CenterImage);
0095     void  setSelectionX(int x);
0096     void  setSelectionY(int y);
0097     void  setSelectionWidth(int w);
0098     void  setSelectionHeight(int h);
0099     void  setSelectionOrientation(int orient);
0100     void  setIsDrawingSelection(bool draw);
0101     void  setPreciseCrop(bool precise);
0102     void  setAutoOrientation(bool orientation);
0103     void  setSelectionAspectRatioType(int aspectRatioType);
0104     void  setSelectionAspectRatioValue(int widthRatioValue, int heightRatioValue);
0105     void  setGoldenGuideTypes(bool drawGoldenSection,  bool drawGoldenSpiralSection,
0106                               bool drawGoldenSpiral,   bool drawGoldenTriangle,
0107                               bool flipHorGoldenGuide, bool flipVerGoldenGuide);
0108 
0109     int   getOriginalImageWidth()   const;
0110     int   getOriginalImageHeight()  const;
0111     QRect getRegionSelection()      const;
0112 
0113     int   getMinWidthRange()        const;
0114     int   getMinHeightRange()       const;
0115     int   getMaxWidthRange()        const;
0116     int   getMaxHeightRange()       const;
0117     int   getWidthStep()            const;
0118     int   getHeightStep()           const;
0119 
0120     bool  preciseCropAvailable()    const;
0121 
0122     void  resetSelection();
0123     void  maxAspectSelection();
0124 
0125     ImageIface* imageIface()        const;
0126 
0127 public Q_SLOTS:
0128 
0129     void slotGuideLines(int guideLinesType);
0130     void slotChangeGuideColor(const QColor& color);
0131     void slotChangeGuideSize(int size);
0132 
0133 Q_SIGNALS:
0134 
0135     void signalSelectionMoved(const QRect& rect);
0136     void signalSelectionChanged(const QRect& rect);
0137     void signalSelectionOrientationChanged(int newOrientation);
0138 
0139 protected:
0140 
0141     void paintEvent(QPaintEvent*)           override;
0142     void mousePressEvent(QMouseEvent*)      override;
0143     void mouseReleaseEvent(QMouseEvent*)    override;
0144     void mouseMoveEvent(QMouseEvent*)       override;
0145     void resizeEvent(QResizeEvent*)         override;
0146 
0147 private:
0148 
0149     // Recalculate the target selection position and emit 'signalSelectionMoved'.
0150     void   regionSelectionMoved();
0151     void   regionSelectionChanged();
0152 
0153     QPoint convertPoint(const QPoint& pm, bool localToReal=true) const;
0154     QPoint convertPoint(int x, int y, bool localToReal=true)     const;
0155     QPoint opposite()                                            const;
0156 
0157     void   normalizeRegion();
0158     void   reverseRatioValues();
0159     void   applyAspectRatio(bool useHeight, bool repaintWidget=true);
0160     void   updatePixmap();
0161     void   placeSelection(const QPoint& pm, bool symmetric, const QPoint& center);
0162     void   setCursorResizing();
0163 
0164     float  distance(const QPoint& a, const QPoint& b) const;
0165     int    computePreciseSize(int size, int step)     const;
0166 
0167     // drawing functions for the various guide types
0168     void   drawRulesOfThirds(QPainter& p, const int& xThird, const int& yThird);
0169     void   drawRulesOfCenter(QPainter& p, const int& xHalf, const int& yHalf);
0170     void   drawDiagonalMethod(QPainter& p, const int& w, const int& h);
0171     void   drawHarmoniousTriangles(QPainter& p, const int& dst);
0172     void   drawGoldenMean(QPainter& p, const QRect& R1, const QRect& R2,
0173                           const QRect& R3, const QRect& R4, const QRect& R5,
0174                           const QRect& R6, const QRect& R7);
0175 
0176     void setup(int width, int height,
0177                int widthRatioValue = 1, int heightRatioValue = 1,
0178                int aspectRatio = RATIO01X01, int orient = Landscape,
0179                int guideLinesType = GuideNone);
0180 
0181 private:
0182 
0183     class Private;
0184     Private* const d;
0185 };
0186 
0187 } // namespace DigikamEditorRatioCropToolPlugin
0188 
0189 #endif // DIGIKAM_EDITOR_RATIO_CROP_WIDGET_H