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 // No context menu here. Setting this avoids long-presses from delaying
36 // inputs or dismissing the palette, see KisLongPressEventFilter.cpp.
37 setContextMenuPolicy(Qt::PreventContextMenu);
38 KisConfig cfg(true);
41}
42
46
48{
49 if (m_canvas) {
50 m_canvas->image()->disconnect(this);
51 m_canvas->displayColorConverter()->disconnect(this);
52 }
53
55
56 if (m_canvas) {
57 connect(m_canvas->displayColorConverter(), SIGNAL(displayConfigurationChanged()), SLOT(startUpdateCanvasProjection()));
58 connect(m_canvas->canvasController()->proxyObject, SIGNAL(canvasStateChanged()), this, SLOT(update()), Qt::UniqueConnection);
59 connect(m_canvas->viewManager()->mainWindow(), SIGNAL(themeChanged()), this, SLOT(slotThemeChanged()), Qt::UniqueConnection);
60 }
61}
62
64{
65 if (!m_canvas || !m_canvas->image()) {
66 return;
67 }
68
69 QSize imageSize(m_canvas->image()->bounds().size());
70
71 const qreal hScale = 1.0 * this->width() / imageSize.width();
72 const qreal vScale = 1.0 * this->height() / imageSize.height();
73
74 m_previewScale = qMin(hScale, vScale);
75 m_previewSize = imageSize * m_previewScale;
77
78}
79
81{
82 return
83 canvas->viewManager()->idleTasksManager()->
84 addIdleTaskWithGuard([this](KisImageSP image) {
85 const KisDisplayConfig config = m_canvas->displayColorConverter()->displayConfig();
86
87 // If the widget is presented on a device with a pixel ratio > 1.0, we must compensate for it
88 // by increasing the thumbnail's resolution. Otherwise it will appear blurry.
89 QSize thumbnailSize = m_previewSize * devicePixelRatioF();
90
91 if ((thumbnailSize.width() > image->width()) || (thumbnailSize.height() > image->height())) {
92 thumbnailSize.scale(image->size(), Qt::KeepAspectRatio);
93 }
94
96 new KisImageThumbnailStrokeStrategy(image->projection(), image->bounds(), thumbnailSize, isPixelArt(), config.profile, config.intent, config.conversionFlags);
97
98 connect(strategy, SIGNAL(thumbnailUpdated(QImage)), this, SLOT(updateThumbnail(QImage)));
99
100 return strategy;
101 });
102}
103
105{
106 m_pixmap = QPixmap();
107 m_oldPixmap = QPixmap();
108}
109
111{
112 return m_previewScale > 1;
113}
114
116{
117 return QPointF((width() - previewSize.width()) / 2.0f, (height() - previewSize.height()) / 2.0f);
118}
119
121{
122 if (m_canvas) {
123 const QRectF &canvasRect = QRectF(m_canvas->canvasWidget()->rect());
124 return canvasToPreviewTransform().map(canvasRect);
125 }
126 return QPolygonF();
127}
128
130{
131 QTransform previewToImage =
132 QTransform::fromTranslate(-this->width() / 2.0, -this->height() / 2.0) *
133 QTransform::fromScale(1.0 / m_previewScale, 1.0 / m_previewScale) *
134 QTransform::fromTranslate(m_canvas->image()->width() / 2.0, m_canvas->image()->height() / 2.0);
135
136 return previewToImage * m_canvas->coordinatesConverter()->imageToWidgetTransform();
137}
138
140{
141 return previewToCanvasTransform().inverted();
142}
143
148
149void OverviewWidget::resizeEvent(QResizeEvent *event)
150{
151 Q_UNUSED(event);
152 if (m_canvas) {
153 if (!m_oldPixmap.isNull()) {
155 m_pixmap = m_oldPixmap.scaled(m_previewSize, Qt::KeepAspectRatio, Qt::FastTransformation);
156 }
158 }
159}
160
161void OverviewWidget::mousePressEvent(QMouseEvent* event)
162{
163 if (m_canvas) {
164 QPointF previewPos = event->pos();
165
166 if (!previewPolygon().containsPoint(previewPos, Qt::WindingFill)) {
167 const QRect& canvasRect = m_canvas->canvasWidget()->rect();
168 const QPointF newCanvasPos = previewToCanvasTransform().map(previewPos) -
169 QPointF(canvasRect.width() / 2.0f, canvasRect.height() / 2.0f);
170 m_canvas->canvasController()->pan(newCanvasPos.toPoint());
171 }
172 m_lastPos = previewPos;
173 m_dragging = true;
174 Q_EMIT signalDraggingStarted();
175 }
176 event->accept();
177 update();
178}
179
180void OverviewWidget::mouseMoveEvent(QMouseEvent* event)
181{
182 if (m_dragging) {
183 QPointF previewPos = event->pos();
184 const QPointF lastCanvasPos = previewToCanvasTransform().map(m_lastPos);
185 const QPointF newCanvasPos = previewToCanvasTransform().map(event->pos());
186
187 QPointF diff = newCanvasPos - lastCanvasPos;
188 m_canvas->canvasController()->pan(diff.toPoint());
189 m_lastPos = previewPos;
190 }
191 event->accept();
192}
193
194void OverviewWidget::mouseReleaseEvent(QMouseEvent* event)
195{
196 if (m_dragging) {
197 m_dragging = false;
198 Q_EMIT signalDraggingFinished();
199 }
200 event->accept();
201 update();
202}
203
204void OverviewWidget::wheelEvent(QWheelEvent* event)
205{
206 if (m_canvas) {
207 if (event->angleDelta().y() > 0) {
209 } else {
211 }
212 }
213}
214
216{
217 m_pixmap = QPixmap::fromImage(pixmap);
218 m_oldPixmap = m_pixmap.copy();
219 update();
220}
221
223{
224 m_outlineColor = qApp->palette().color(QPalette::Highlight);
225}
226
227
228void OverviewWidget::paintEvent(QPaintEvent* event)
229{
230 QWidget::paintEvent(event);
231
232 if (m_canvas) {
234 QPainter p(this);
235
236 const QRectF previewRect = QRectF(m_previewOrigin, m_previewSize);
237 p.drawPixmap(previewRect.toRect(), m_pixmap);
238
239 QRect r = rect();
240 QPolygonF outline;
241 outline << r.topLeft() << r.topRight() << r.bottomRight() << r.bottomLeft();
242
243 QPen pen;
244 pen.setColor(m_outlineColor);
245 pen.setStyle(Qt::DashLine);
246
247 p.setPen(pen);
248 p.drawPolygon(outline.intersected(previewPolygon()));
249
250 pen.setStyle(Qt::SolidLine);
251 p.setPen(pen);
252 p.drawPolygon(previewPolygon());
253
254 }
255}
256
257
const Params2D p
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)