Krita Source Code Documentation
Loading...
Searching...
No Matches
overviewwidget.cc
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2009 Cyrille Berger <cberger@cberger.net>
3 * SPDX-FileCopyrightText: 2014 Sven Langkamp <sven.langkamp@gmail.com>
4 *
5 * SPDX-License-Identifier: LGPL-2.0-or-later
6 */
7
8
9#include "overviewwidget.h"
10
11#include <QMouseEvent>
12#include <QPainter>
13#include <QCursor>
14
15#include <KoCanvasController.h>
16
17#include <kis_canvas2.h>
18#include <KisViewManager.h>
19#include <kis_image.h>
21#include <kis_config.h>
22#include <QApplication>
25#include <KisMainWindow.h>
26#include "KisIdleTasksManager.h"
27#include <KisDisplayConfig.h>
28
29
31 : KisWidgetWithIdleTask<QWidget>(parent)
32 , m_dragging(false)
33{
34 setMouseTracking(true);
35 KisConfig cfg(true);
38}
39
43
45{
46 if (m_canvas) {
47 m_canvas->image()->disconnect(this);
48 m_canvas->displayColorConverter()->disconnect(this);
49 }
50
52
53 if (m_canvas) {
54 connect(m_canvas->displayColorConverter(), SIGNAL(displayConfigurationChanged()), SLOT(startUpdateCanvasProjection()));
55 connect(m_canvas->canvasController()->proxyObject, SIGNAL(canvasStateChanged()), this, SLOT(update()), Qt::UniqueConnection);
56 connect(m_canvas->viewManager()->mainWindow(), SIGNAL(themeChanged()), this, SLOT(slotThemeChanged()), Qt::UniqueConnection);
57 }
58}
59
61{
62 if (!m_canvas || !m_canvas->image()) {
63 return;
64 }
65
66 QSize imageSize(m_canvas->image()->bounds().size());
67
68 const qreal hScale = 1.0 * this->width() / imageSize.width();
69 const qreal vScale = 1.0 * this->height() / imageSize.height();
70
71 m_previewScale = qMin(hScale, vScale);
72 m_previewSize = imageSize * m_previewScale;
74
75}
76
78{
79 return
80 canvas->viewManager()->idleTasksManager()->
81 addIdleTaskWithGuard([this](KisImageSP image) {
82 const KisDisplayConfig config = m_canvas->displayColorConverter()->displayConfig();
83
84 // If the widget is presented on a device with a pixel ratio > 1.0, we must compensate for it
85 // by increasing the thumbnail's resolution. Otherwise it will appear blurry.
86 QSize thumbnailSize = m_previewSize * devicePixelRatioF();
87
88 if ((thumbnailSize.width() > image->width()) || (thumbnailSize.height() > image->height())) {
89 thumbnailSize.scale(image->size(), Qt::KeepAspectRatio);
90 }
91
93 new KisImageThumbnailStrokeStrategy(image->projection(), image->bounds(), thumbnailSize, isPixelArt(), config.profile, config.intent, config.conversionFlags);
94
95 connect(strategy, SIGNAL(thumbnailUpdated(QImage)), this, SLOT(updateThumbnail(QImage)));
96
97 return strategy;
98 });
99}
100
102{
103 m_pixmap = QPixmap();
104 m_oldPixmap = QPixmap();
105}
106
108{
109 return m_previewScale > 1;
110}
111
113{
114 return QPointF((width() - previewSize.width()) / 2.0f, (height() - previewSize.height()) / 2.0f);
115}
116
118{
119 if (m_canvas) {
120 const QRectF &canvasRect = QRectF(m_canvas->canvasWidget()->rect());
121 return canvasToPreviewTransform().map(canvasRect);
122 }
123 return QPolygonF();
124}
125
127{
128 QTransform previewToImage =
129 QTransform::fromTranslate(-this->width() / 2.0, -this->height() / 2.0) *
130 QTransform::fromScale(1.0 / m_previewScale, 1.0 / m_previewScale) *
131 QTransform::fromTranslate(m_canvas->image()->width() / 2.0, m_canvas->image()->height() / 2.0);
132
133 return previewToImage * m_canvas->coordinatesConverter()->imageToWidgetTransform();
134}
135
137{
138 return previewToCanvasTransform().inverted();
139}
140
145
146void OverviewWidget::resizeEvent(QResizeEvent *event)
147{
148 Q_UNUSED(event);
149 if (m_canvas) {
150 if (!m_oldPixmap.isNull()) {
152 m_pixmap = m_oldPixmap.scaled(m_previewSize, Qt::KeepAspectRatio, Qt::FastTransformation);
153 }
155 }
156}
157
158void OverviewWidget::mousePressEvent(QMouseEvent* event)
159{
160 if (m_canvas) {
161 QPointF previewPos = event->pos();
162
163 if (!previewPolygon().containsPoint(previewPos, Qt::WindingFill)) {
164 const QRect& canvasRect = m_canvas->canvasWidget()->rect();
165 const QPointF newCanvasPos = previewToCanvasTransform().map(previewPos) -
166 QPointF(canvasRect.width() / 2.0f, canvasRect.height() / 2.0f);
167 m_canvas->canvasController()->pan(newCanvasPos.toPoint());
168 }
169 m_lastPos = previewPos;
170 m_dragging = true;
171 Q_EMIT signalDraggingStarted();
172 }
173 event->accept();
174 update();
175}
176
177void OverviewWidget::mouseMoveEvent(QMouseEvent* event)
178{
179 if (m_dragging) {
180 QPointF previewPos = event->pos();
181 const QPointF lastCanvasPos = previewToCanvasTransform().map(m_lastPos);
182 const QPointF newCanvasPos = previewToCanvasTransform().map(event->pos());
183
184 QPointF diff = newCanvasPos - lastCanvasPos;
185 m_canvas->canvasController()->pan(diff.toPoint());
186 m_lastPos = previewPos;
187 }
188 event->accept();
189}
190
191void OverviewWidget::mouseReleaseEvent(QMouseEvent* event)
192{
193 if (m_dragging) {
194 m_dragging = false;
195 Q_EMIT signalDraggingFinished();
196 }
197 event->accept();
198 update();
199}
200
201void OverviewWidget::wheelEvent(QWheelEvent* event)
202{
203 if (m_canvas) {
204 if (event->angleDelta().y() > 0) {
206 } else {
208 }
209 }
210}
211
213{
214 m_pixmap = QPixmap::fromImage(pixmap);
215 m_oldPixmap = m_pixmap.copy();
216 update();
217}
218
220{
221 m_outlineColor = qApp->palette().color(QPalette::Highlight);
222}
223
224
225void OverviewWidget::paintEvent(QPaintEvent* event)
226{
227 QWidget::paintEvent(event);
228
229 if (m_canvas) {
231 QPainter p(this);
232
233 const QRectF previewRect = QRectF(m_previewOrigin, m_previewSize);
234 p.drawPixmap(previewRect.toRect(), m_pixmap);
235
236 QRect r = rect();
237 QPolygonF outline;
238 outline << r.topLeft() << r.topRight() << r.bottomRight() << r.bottomLeft();
239
240 QPen pen;
241 pen.setColor(m_outlineColor);
242 pen.setStyle(Qt::DashLine);
243
244 p.setPen(pen);
245 p.drawPolygon(outline.intersected(previewPolygon()));
246
247 pen.setStyle(Qt::SolidLine);
248 p.setPen(pen);
249 p.drawPolygon(previewPolygon());
250
251 }
252}
253
254
const Params2D p
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
KisDisplayColorConverter displayColorConverter
KisCoordinatesConverter * coordinatesConverter
KisImageWSP image() const
KisViewManager * viewManager() const
KisAbstractCanvasWidget * canvasWidget
KisDisplayConfig This class keeps track of the color management configuration for image to display....
KoColorConversionTransformation::ConversionFlags conversionFlags
const KoColorProfile * profile
KoColorConversionTransformation::Intent intent
KisPaintDeviceSP projection() const
qint32 width() const
QSize size() const
Definition kis_image.h:547
qint32 height() const
QRect bounds() const override
KisMainWindow * mainWindow() const
KisIdleTasksManager * idleTasksManager()
virtual void setCanvas(KisCanvas2 *canvas)
KoCanvasController * canvasController() const
QPointer< KoCanvasControllerProxyObject > proxyObject
virtual void zoomIn(const KoViewTransformStillPoint &stillPoint)=0
zooms in keeping stillPoint not moved.
virtual void pan(const QPoint &distance)=0
virtual void zoomOut(const KoViewTransformStillPoint &stillPoint)=0
zooms out keeping stillPoint not moved.
void mousePressEvent(QMouseEvent *event) override
QTransform canvasToPreviewTransform()
QPolygonF previewPolygon()
void startUpdateCanvasProjection()
void updateThumbnail(QImage pixmap)
void resizeEvent(QResizeEvent *event) override
void wheelEvent(QWheelEvent *event) override
void clearCachedState() override
void mouseReleaseEvent(QMouseEvent *event) override
void paintEvent(QPaintEvent *event) override
void setCanvas(KisCanvas2 *canvas) override
void recalculatePreviewDimensions()
void signalDraggingFinished()
~OverviewWidget() override
bool isPixelArt()
isPixelArt checks if the preview is bigger than the image itself
void mouseMoveEvent(QMouseEvent *event) override
QTransform previewToCanvasTransform()
KisIdleTasksManager::TaskGuard registerIdleTask(KisCanvas2 *canvas) override
OverviewWidget(QWidget *parent=0)
void signalDraggingStarted()
QPointF m_previewOrigin
QPointF calculatePreviewOrigin(QSize previewSize)