File indexing completed on 2024-12-22 04:13:13

0001 /*
0002   *  SPDX-FileCopyrightText: 2017 Scott Petrovic <scottpetrovic@gmail.com>
0003   *
0004   *  SPDX-License-Identifier: GPL-2.0-or-later
0005   */
0006 
0007 #ifndef _KIS_PRESET_LIVE_PREVIEW_
0008 #define _KIS_PRESET_LIVE_PREVIEW_
0009 
0010 #include <QImage>
0011 #include <QGraphicsScene>
0012 #include <QGraphicsView>
0013 #include <QPainterPath>
0014 #include <QGraphicsPixmapItem>
0015 
0016 #include "kis_paintop_preset.h"
0017 #include "KoColorSpaceRegistry.h"
0018 #include "kis_paint_layer.h"
0019 #include "kis_painter.h"
0020 #include "kis_distance_information.h"
0021 #include "kis_painting_information_builder.h"
0022 #include <kis_image.h>
0023 #include <kis_types.h>
0024 #include <KoColor.h>
0025 #include "kis_signal_compressor.h"
0026 
0027 class KoCanvasResourceProvider;
0028 
0029 /**
0030  * Widget for displaying a live brush preview of your
0031  * selected brush. It listens for signalsetting changes
0032  * that the brush preset outputs and updates the preview
0033  * accordingly. This class can be added to a UI file
0034  * similar to how a QGraphicsView is added
0035  */
0036 class KisPresetLivePreviewView : public QGraphicsView
0037 {
0038     Q_OBJECT
0039 
0040 
0041 public:
0042 
0043     KisPresetLivePreviewView(QWidget *parent);
0044     ~KisPresetLivePreviewView();
0045 
0046     /**
0047      * @brief one time setup for initialization of many variables.
0048      * This live preview might be in a UI file, so make sure to
0049      * call this before starting to use it
0050      */
0051     void setup(KoCanvasResourceProvider* resourceManager);
0052 
0053     /**
0054      * @brief set the current preset from resource manager for the live preview to use.
0055      * Good to call this every stroke update in case the preset has changed
0056      * @param preset the current preset from the resource manager
0057      */
0058     void setCurrentPreset(KisPaintOpPresetSP preset);
0059     void requestUpdateStroke();
0060 
0061 private Q_SLOTS:
0062     void updateStroke();
0063     void slotPreviewGenerationCompleted();
0064 
0065 private:
0066 
0067     ///internally sets the Resource Provider for brush preview (allowing gradients in preview)
0068     KoCanvasResourceProvider* m_resourceManager {nullptr};
0069 
0070     /// internally sets the image area for brush preview
0071     KisImageSP m_image;
0072 
0073     /// internally sets the layer area for brush preview
0074     KisLayerSP m_layer;
0075 
0076     /// internally sets the color space for brush preview
0077     const KoColorSpace *m_colorSpace {nullptr};
0078 
0079     /// the color which is used for rendering the stroke
0080     KoColor m_paintColor;
0081 
0082     /// the scene that can add items like text and the brush stroke image
0083     QGraphicsScene *m_brushPreviewScene {nullptr};
0084 
0085     /// holds the preview brush stroke data
0086     QGraphicsPixmapItem *m_sceneImageItem {nullptr};
0087 
0088     /// holds the 'no preview available' text object
0089     QGraphicsTextItem *m_noPreviewText {nullptr};
0090 
0091     /// holds the width and height of the image of the brush preview
0092     /// Probably can later add set functions to make this customizable
0093     /// It is hard-coded to 1200 x 400 for right now for image size
0094     QRect m_canvasSize;
0095 
0096     /// convenience variable used internally when positioning the objects
0097     /// and points in the scene
0098     QPointF m_canvasCenterPoint;
0099 
0100     /// internal variables for constructing the stroke start and end shape
0101     /// there are two points that construct the "S" curve with this
0102     KisDistanceInformation m_currentDistance;
0103     QPainterPath m_curvedLine;
0104     KisPaintInformation m_curvePointPI1;
0105     KisPaintInformation m_curvePointPI2;
0106 
0107     /// internally stores the current preset.
0108     /// See setCurrentPreset(KisPaintOpPresetSP preset)
0109     /// for setting this externally
0110     KisPaintOpPresetSP m_currentPreset;
0111 
0112     /// internal reference for internal brush size
0113     /// used to check if our brush size has changed
0114     /// do zooming and other things internally if it has changed
0115     float m_currentBrushSize {1.0};
0116 
0117     bool m_previewGenerationInProgress {false};
0118     KisSignalCompressor m_updateCompressor;
0119 
0120     /// the range of brush sizes that will control zooming in/out
0121     const float m_minBrushVal {10.0};
0122     const float m_maxBrushVal {100.0};
0123 
0124     /// range of scale values. 1.0 == 100%
0125     const qreal m_minScale {1.0};
0126     const qreal m_maxScale {0.3};
0127 
0128     /// multiplier that is used for lengthening the brush stroke points
0129     const float m_minStrokeScale {0.4}; // for smaller brush stroke
0130     const float m_maxStrokeScale {1.0}; // for larger brush stroke
0131 
0132 
0133     /**
0134      * @brief works as both clearing the previous stroke, providing
0135      * striped backgrounds for smudging brushes, and text if there is no preview
0136      */
0137     void paintBackground();
0138 
0139     /**
0140      * @brief creates and performs the actual stroke that goes on top of the background
0141      * this is internally and should always be called after the paintBackground()
0142      */
0143     void setupAndPaintStroke();
0144 
0145     void changeEvent(QEvent*) override;
0146 };
0147 
0148 #endif