12#include <QMutexLocker>
54#if KRITA_USE_SURFACE_COLOR_MANAGEMENT_API
59class KisUpdateSchedulerLockAdapter
63 : m_scheduler(scheduler)
68 m_scheduler->barrierLock();
72 return m_scheduler->tryBarrierLock();
76 m_scheduler->unlock();
103 QMutexLocker locker(&
m_lock);
105 Q_FOREACH (
const QRect &rc, rects) {
162 , m_toolMode(HOVERING)
163 , isModeManuallySet(false)
165 , m_linkCanvasZoomLevel(true)
166 , m_canvasScaleX(1.0)
167 , m_canvasScaleY(1.0)
168 , m_scratchpadScaleX(1.0)
169 , m_scratchpadScaleY(1.0)
170 , m_accumulatedMouseDelta(0)
172 , m_resourceProvider(0)
175 setAutoFillBackground(
false);
176 setMouseTracking(
true);
213 const int canvasScreenNumber = qApp->screens().indexOf(screen);
215#if KRITA_USE_SURFACE_COLOR_MANAGEMENT_API
257 const int angleDelta =
event->angleDelta().y();
266 if (event->source() == Qt::MouseEventSource::MouseEventSynthesizedBySystem) {
274 if (angleDelta == 0) {
285 QPointF position =
event->position();
295 qreal scaleFactor = 0.5;
296 if (
scaleX < 1) scaleFactor = 0.05;
301 qreal scaleFactor = 0.5;
302 if (
scaleX <= 1) scaleFactor = 0.05;
323 QPoint panPosition = QPointF( docPosition - offsetPosition).toPoint();
326 panTo(panPosition.x(), panPosition.y());
334 if (!isEnabled())
return;
341 if (event->
button() == Qt::LeftButton ||
342 event->
button() == Qt::MiddleButton ||
343 event->
button() == Qt::RightButton) {
366 if (!isEnabled())
return;
398 if (!isEnabled())
return;
401 if (event->
point.isNull() ==
false) {
447 setCursor(QCursor(Qt::ClosedHandCursor));
466 setCursor(QCursor(Qt::OpenHandCursor));
574 if (contentsF.isEmpty() || viewportF.isEmpty())
return;
576 qreal contentRatio = contentsF.width() / contentsF.height();
577 qreal viewportRatio = viewportF.width() / viewportF.height();
579 if (viewportRatio > contentRatio) {
580 scale = viewportF.height() / contentsF.height();
582 scale = viewportF.width() / contentsF.width();
616 QPoint panPosition = QPointF( contentsF.center() - viewportF/2 ).toPoint() ;
618 panTo(panPosition.x(), panPosition.y());
724 const int screenId = qApp->screens().indexOf(screen);
738 QRect alignedImageRect =
742 QPointF offset = alignedImageRect.topLeft();
748 alignedImageRect.x(),
749 alignedImageRect.y(),
750 alignedImageRect.width(),
751 alignedImageRect.height(),
761 if (event->rect().width() < image.rect().width()) {
762 gc.setRenderHints(QPainter::SmoothPixmapTransform,
true);
764 gc.setRenderHints(QPainter::SmoothPixmapTransform,
false);
767 gc.drawImage(QRectF(event->rect()), image, imageRect.translated(-offset));
769 QBrush brush(Qt::lightGray);
770 QPen pen(brush, 1, Qt::DotLine);
777 QColor color(Qt::lightGray);
778 color.setAlphaF(0.5);
779 QBrush disabledBrush(color);
780 gc.fillRect(event->rect(), disabledBrush);
787 QWidget::resizeEvent(event);
801 const QColor &defaultColor)
836 if (mode.toLower() ==
"painting") {
839 }
else if (mode.toLower() ==
"panning") {
841 setCursor(Qt::OpenHandCursor);
842 }
else if (mode.toLower() ==
"colorsampling") {
877 Qt::IgnoreAspectRatio,
878 Qt::SmoothTransformation);
898 QRect imageRect(QPoint(), overlayRect.size());
900 QImage scaledImage = loadedImage.scaled(overlayRect.size(),
901 Qt::IgnoreAspectRatio,
902 Qt::SmoothTransformation);
910 painter.
bitBlt(overlayRect.topLeft(), device, imageRect);
928 QRect imageSize = image.rect();
938 painter.
bitBlt(imageSize.topLeft(), device, imageSize);
961 QRect imageRect(QPoint(), overlayRect.size());
963 QImage scaledImage =
m_presetImage.scaled(overlayRect.size(),
964 Qt::IgnoreAspectRatio,
965 Qt::SmoothTransformation);
973 painter.
bitBlt(overlayRect.topLeft(), device, imageRect);
983 const int screenId = qApp->screens().indexOf(screen);
999 paintDevice->
clear();
1012 QColor transQColor(0,0,0,0);
1021 paintDevice->
clear();
1035 const QPoint &gradientVectorEnd,
1038 bool reverseGradient,
1052 paintDevice->
clear();
1057 if (gradientVectorStart == gradientVectorEnd && gradientVectorStart == QPoint()) {
1060 gradientRect.bottomRight(),
1064 gradientRect.left(), gradientRect.top(),
1065 gradientRect.width(), gradientRect.height(),
1073 gradientRect.left(), gradientRect.top(),
1074 gradientRect.width(), gradientRect.height(),
1090 gradientRect.bottomRight(),
1111 paintDevice->
clear();
1115 painter.
setWidth(patternRect.width());
1116 painter.
setHeight(patternRect.height());
1117 painter.
fillPattern(0, 0, paintDevice, transform);
1135 paintDevice->
clear();
1152 paintDevice->
clear();
1218#include "kis_scratch_pad.moc"
float value(const T *src, size_t ch)
#define KIS_DECLARE_ADAPTED_LOCK(Name, Adapter)
const quint8 OPACITY_OPAQUE_U8
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
KoCanvasResourceProvider * resourceManager()
KoPatternSP currentPattern() const
KoAbstractGradientSP currentGradient() const
KisNodeSP currentNode() const
KisImageWSP currentImage() const
static KisConfigNotifier * instance()
CanvasSurfaceMode canvasSurfaceColorSpaceManagementMode(bool defaultValue=false) const
qint32 checkSize(bool defaultValue=false) const
static QCursor load(const QString &cursorName, int hotspotX=-1, int hotspotY=-1)
KoColorConversionTransformation::ConversionFlags conversionFlags
static Options optionsFromKisConfig(const KisConfig &cfg)
const KoColorProfile * profile
KoColorConversionTransformation::Intent intent
void fillPattern(int startX, int startY, KisPaintDeviceSP sourceDevice, QTransform patternTransform=QTransform())
KisPaintDeviceSP projection() const
KisDisplayConfig uiDisplayConfig() const
State createInitializingConfig(bool isCanvasOpenGL, int screenId, KisProofingConfigurationSP proofingConfig) const
State onConfigChanged(const State &oldState, int screenId, KisConfig::CanvasSurfaceMode surfaceMode, const KisDisplayConfig::Options &options) const
State onScreenChanged(const State &oldState, int screenId) const
State onGuiSurfaceFormatChanged(const State &oldState, const KoColorProfile *uiProfile) const
void setDefaultPixel(const KoColor &defPixel)
QRect nonDefaultPixelArea() const
void setDefaultBounds(KisDefaultBoundsBaseSP bounds)
QRect exactBounds() const
const KoColorSpace * colorSpace() const
QImage convertToQImage(const KoColorProfile *dstProfile, qint32 x, qint32 y, qint32 w, qint32 h, KoColorConversionTransformation::Intent renderingIntent=KoColorConversionTransformation::internalRenderingIntent(), KoColorConversionTransformation::ConversionFlags conversionFlags=KoColorConversionTransformation::internalConversionFlags()) const
KisDefaultBoundsBaseSP defaultBounds() const
void convertFromQImage(const QImage &image, const KoColorProfile *profile, qint32 offsetX=0, qint32 offsetY=0)
QRect calculateExactBounds(bool nonDefaultOnly) const
void beginTransaction(const KUndo2MagicString &transactionName=KUndo2MagicString(), int timedID=-1)
Begin an undoable paint operation.
void setGradient(const KoAbstractGradientSP gradient)
void bitBlt(qint32 dstX, qint32 dstY, const KisPaintDeviceSP srcDev, qint32 srcX, qint32 srcY, qint32 srcWidth, qint32 srcHeight)
void setPattern(const KoPatternSP pattern)
Set the current pattern.
void sigRootSurfaceProfileChanged(const KoColorProfile *profile) const
KisScratchPadDefaultBounds(KisScratchPad *scratchPad)
~KisScratchPadDefaultBounds() override
QRect bounds() const override
KisScratchPad * m_scratchPad
void * sourceCookie() const override
void setWidgetToDocumentTransform(const QTransform &transform)
KisScratchPad * m_scratchPad
KisScratchPadNodeListener(KisScratchPad *scratchPad)
void requestProjectionUpdate(KisNode *node, const QVector< QRect > &rects, KisProjectionUpdateFlags flags) override
void fillPattern(QTransform transform)
bool updateViewportImpl()
void setPresetImage(const QImage &image)
void resizeEvent(QResizeEvent *event) override
bool canvasZoomLink()
return True if the scratchpad zoom level stay in sync with canvas
qreal scaleY()
return current scale Y applied on scratchpad (whatever the zoom source is - canvas zoom or set manual...
QImage cutoutOverlay() const
return the contents of the area under the cutoutOverlay rect
void setCanvasZoomLink(bool value)
should the scratchpad zoom level stay in sync with canvas
void paintEvent(QPaintEvent *event) override
void fillLayer(bool fullContent)
Fill the area with what is on your current canvas.
QRect imageBounds() const
KisScratchPadEventFilter * m_eventFilter
void imageUpdated(const QRect &rect)
bool m_linkCanvasZoomLevel
void endStroke(KoPointerEvent *event)
void pointerMove(KoPointerEvent *event)
void sigUpdateCanvas(const QRect &rect)
void scaleReset()
reset scale value (to 1.0) and reinit position
void scaleToFit()
calculate and apply scale to fit content in viewport
KisCanvasResourceProvider * m_resourceProvider
KisUndoStore * m_undoStore
void loadScratchpadImage(QImage image)
bool setScaleImpl(qreal scaleX, qreal scaleY)
void beginStroke(KoPointerEvent *event)
KisPaintingInformationBuilder * m_infoBuilder
KisUpdateScheduler * m_updateScheduler
QCursor m_colorSamplerCursor
QTransform documentToWidget() const
QTransform m_scaleTransform
KisNodeGraphListener * m_nodeListener
void viewportChanged(const QRect rect)
signal is emitted when scratchpad viewport has been modified (pan, zoom)
void slotUpdateCanvas(const QRect &rect)
KisDisplayConfig m_displayConfig
void colorSelected(const KoColor &color)
KisPaintLayerSP m_paintLayer
Mode modeFromButton(Qt::MouseButton button) const
void doStroke(KoPointerEvent *event)
void sample(KoPointerEvent *event)
void updateTransformations()
bool setScale(qreal scaleX, qreal scaleY)
allow to manually set scratchpad scale when NOT linked to canvas zoom
void pointerPress(KoPointerEvent *event)
void setFillColor(QColor newColor)
void beginPan(KoPointerEvent *event)
void wheelDelta(QWheelEvent *event)
void panTo(qint32 x, qint32 y)
pan scratchpad content to given position
void endPan(KoPointerEvent *event)
void setModeType(QString modeName)
change the mode explicitly to paint, mix, or pan
void pointerRelease(KoPointerEvent *event)
qreal scaleX()
return current scale X applied on scratchpad (whatever the zoom source is - canvas zoom or set manual...
QRect viewportBounds() const
int m_accumulatedMouseDelta
KisPostExecutionUndoAdapter * m_undoAdapter
void setCutoutOverlayRect(const QRect &rc)
set the specified rect as the area taken for
QTransform widgetToDocument() const
KisScratchPad(QWidget *parent=0)
void panCenter()
pan scratchpad content to center content in viewport
friend class KisScratchPadPaintingInformationBuilder
void slotScreenChanged(QScreen *screen)
QImage copyScratchpadImageData()
QScopedPointer< KisToolFreehandHelper > m_helper
void scaleChanged(qreal scale)
signal is emitted when scratchpad scale is changed (from zoom canvas or manually)
QRect contentBounds() const
QTransform m_translateTransform
void setupScratchPad(KisCanvasResourceProvider *resourceProvider, const QColor &defaultColor)
void assignNewSurfaceState(const KisMultiSurfaceStateManager::State &newState)
void contentChanged()
signal is emitted when scratchpad content is changed (stroke or fill)
KisMultiSurfaceStateManager m_multiSurfaceStateManager
friend KisScratchPadEventFilter
~KisScratchPad() override
void doPan(KoPointerEvent *event)
void setModeManually(bool value)
QScopedPointer< KisScreenMigrationTracker > m_screenMigrationTracker
KisMultiSurfaceStateManager::State m_multiSurfaceState
void paintCustomImage(const QImage &loadedImage)
void setOnScreenResolution(qreal scaleX, qreal scaleY)
void sigScreenChanged(QScreen *screen)
void setOpacity(quint8 alpha)
const KoColorSpace * colorSpace() const
return the current colorSpace
Qt::MouseButton button() const
return button pressed (see QMouseEvent::button());
QPointF point
The point in document coordinates.
static bool qFuzzyCompare(half p1, half p2)
#define KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(cond, val)
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
#define BORDER_SIZE(scale)
QString button(const QWheelEvent &ev)
virtual KisPaintDeviceSP projection() const =0
virtual QRect exactBounds() const
bool paintGradient(const QPointF &gradientVectorStart, const QPointF &gradientVectorEnd, enumGradientRepeat repeat, double antiAliasThreshold, bool reverseGradient, qint32 startx, qint32 starty, qint32 width, qint32 height, bool useDithering=false)
void setGradientShape(enumGradientShape shape)
KisPaintDeviceSP projection() const override
KisLayerProjectionPlaneSP projectionPlane
KisMultiSurfaceDisplayConfig multiConfig
virtual void requestProjectionUpdate(KisNode *node, const QVector< QRect > &rects, KisProjectionUpdateFlags flags)
void setGraphListener(KisNodeGraphListener *graphListener)
QRect exactBounds() const override
KisPaintDeviceSP paintDevice
static KoColorSpaceRegistry * instance()