1
2
3 #include "cleanupswatch.h"
4 #include "trop.h"
5 #include "toonzqt/gutil.h"
6 #include <QHBoxLayout>
7 #include <QBrush>
8 #include <QPainter>
9 #include <QMouseEvent>
10 #include <QIcon>
11 #include <QPushButton>
12 #include <QActionGroup>
13 #include <QToolBar>
14 #include "toonz/tcleanupper.h"
15 #include "toonzqt/dvdialog.h"
CleanupSwatch(QWidget * parent,int lx,int ly)16 CleanupSwatch::CleanupSwatch(QWidget *parent, int lx, int ly)
17 : QWidget(parent)
18 , m_lx(lx)
19 , m_ly(ly)
20 , m_enabled(false)
21 , m_viewAff()
22 //, m_lastRasCleanupped()
23 {
24 setStyleSheet("background: transparent");
25 QHBoxLayout *layout = new QHBoxLayout(this);
26 layout->setMargin(0);
27 layout->setSpacing(0);
28
29 m_leftSwatch = new CleanupSwatchArea(this, true);
30
31 layout->addWidget(m_leftSwatch);
32
33 DVGui::Separator *sep = new DVGui::Separator();
34 sep->setFixedWidth(1);
35 sep->setOrientation(false);
36 layout->addWidget(sep);
37
38 m_rightSwatch = new CleanupSwatchArea(this, false);
39 layout->addWidget(m_rightSwatch);
40
41 setLayout(layout);
42 }
43
44 //---------------------------------------------------------------------
45
enable(bool state)46 void CleanupSwatch::enable(bool state) {
47 m_enabled = state;
48 if (!m_enabled) {
49 m_resampledRaster = TRasterP();
50 // m_lastRasCleanupped = TRasterP();
51 m_origRaster = TRasterP();
52 m_viewAff = TAffine();
53 m_resampleAff = TAffine();
54 m_leftSwatch->updateRaster();
55 m_rightSwatch->updateRaster();
56 }
57 }
58
59 //------------------------------------------------------------------------------
60 /*
61 void CleanupSwatch::hideEvent(QHideEvent* e)
62 {
63 m_enabledAct->setChecked(false);
64 }*/
65
66 //----------------------------------------------------------------
67
CleanupSwatchArea(CleanupSwatch * parent,bool isLeft)68 CleanupSwatch::CleanupSwatchArea::CleanupSwatchArea(CleanupSwatch *parent,
69 bool isLeft)
70 : QWidget(parent), m_isLeft(isLeft), m_sw(parent) {
71 setMinimumHeight(150);
72
73 // The following helps in re-establishing focus for wheel events
74 setFocusPolicy(Qt::WheelFocus);
75 setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
76 }
77
78 //----------------------------------------------------------------
79
mousePressEvent(QMouseEvent * event)80 void CleanupSwatch::CleanupSwatchArea::mousePressEvent(QMouseEvent *event) {
81 if (!m_sw->m_resampledRaster || m_sw->m_lx == 0 || m_sw->m_ly == 0) return;
82 // if (m_sw->m_lastRasCleanupped)
83 // TRop::addBackground(m_sw->m_lastRasCleanupped, TPixel::White);
84 m_pos = event->pos();
85
86 if (event->button() != Qt::MidButton || !m_sw->m_resampledRaster) {
87 event->ignore();
88 return;
89 m_panning = false;
90 } else
91 m_panning = true;
92 }
93
94 //-----------------------------------------------------------------------------
95 namespace {
96 #define ZOOMLEVELS 33
97 #define NOZOOMINDEX 20
98 double ZoomFactors[ZOOMLEVELS] = {
99 0.001, 0.002, 0.003, 0.004, 0.005, 0.007, 0.01, 0.015, 0.02, 0.03, 0.04,
100 0.05, 0.0625, 0.0833, 0.125, 0.167, 0.25, 0.333, 0.5, 0.667, 1, 2,
101 3, 4, 5, 6, 7, 8, 12, 16, 24, 32, 40};
102
getQuantizedZoomFactor(double zf,bool forward)103 double getQuantizedZoomFactor(double zf, bool forward) {
104 if (forward && (zf > ZoomFactors[ZOOMLEVELS - 1] ||
105 areAlmostEqual(zf, ZoomFactors[ZOOMLEVELS - 1], 1e-5)))
106 return zf;
107 else if (!forward &&
108 (zf < ZoomFactors[0] || areAlmostEqual(zf, ZoomFactors[0], 1e-5)))
109 return zf;
110
111 assert((!forward && zf > ZoomFactors[0]) ||
112 (forward && zf < ZoomFactors[ZOOMLEVELS - 1]));
113 int i = 0;
114 for (i = 0; i <= ZOOMLEVELS - 1; i++)
115 if (areAlmostEqual(zf, ZoomFactors[i], 1e-5)) zf = ZoomFactors[i];
116
117 if (forward && zf < ZoomFactors[0])
118 return ZoomFactors[0];
119 else if (!forward && zf > ZoomFactors[ZOOMLEVELS - 1])
120 return ZoomFactors[ZOOMLEVELS - 1];
121
122 for (i = 0; i < ZOOMLEVELS - 1; i++)
123 if (ZoomFactors[i + 1] - zf >= 0 && zf - ZoomFactors[i] >= 0) {
124 if (forward && ZoomFactors[i + 1] == zf)
125 return ZoomFactors[i + 2];
126 else if (!forward && ZoomFactors[i] == zf)
127 return ZoomFactors[i - 1];
128 else
129 return forward ? ZoomFactors[i + 1] : ZoomFactors[i];
130 }
131 return ZoomFactors[NOZOOMINDEX];
132 }
133
134 } // namespace
135 //-----------------------------------------------------------------------------
136
keyPressEvent(QKeyEvent * event)137 void CleanupSwatch::CleanupSwatchArea::keyPressEvent(QKeyEvent *event) {
138 if (!m_sw->m_resampledRaster || m_sw->m_lx == 0 || m_sw->m_ly == 0) return;
139 int key = event->key();
140 if (key != '+' && key != '-' && key != '0') return;
141
142 if (key == '0')
143 m_sw->m_viewAff = TAffine();
144 else {
145 bool forward = (key == '+');
146
147 double currZoomScale = sqrt(m_sw->m_viewAff.det());
148 double factor = getQuantizedZoomFactor(currZoomScale, forward);
149
150 double minZoom =
151 std::min((double)m_sw->m_lx / m_sw->m_resampledRaster->getLx(),
152 (double)m_sw->m_ly / m_sw->m_resampledRaster->getLy());
153 if ((!forward && factor < minZoom) || (forward && factor > 40.0)) return;
154
155 TPointD delta(0.5 * width(), 0.5 * height());
156 m_sw->m_viewAff = (TTranslation(delta) * TScale(factor / currZoomScale) *
157 TTranslation(-delta)) *
158 m_sw->m_viewAff;
159 }
160 m_sw->m_leftSwatch->updateRaster();
161 m_sw->m_rightSwatch->updateRaster();
162 }
163
164 //-----------------------------------------------------------------------------
mouseReleaseEvent(QMouseEvent * event)165 void CleanupSwatch::CleanupSwatchArea::mouseReleaseEvent(QMouseEvent *event) {
166 m_sw->m_rightSwatch->updateRaster();
167 m_panning = false;
168 }
169
170 //----------------------------------------------------------------
mouseMoveEvent(QMouseEvent * event)171 void CleanupSwatch::CleanupSwatchArea::mouseMoveEvent(QMouseEvent *event) {
172 if (!m_panning) return;
173
174 TPoint curPos = TPoint(event->pos().x(), event->pos().y());
175
176 QPoint delta = event->pos() - m_pos;
177 if (delta == QPoint()) return;
178 TAffine oldAff = m_sw->m_viewAff;
179 m_sw->m_viewAff = TTranslation(delta.x(), -delta.y()) * m_sw->m_viewAff;
180
181 m_sw->m_leftSwatch->updateRaster();
182 m_sw->m_rightSwatch->updateRaster(true);
183
184 m_pos = event->pos();
185 }
186
187 //---------------------------------------------------------------
188
wheelEvent(QWheelEvent * event)189 void CleanupSwatch::CleanupSwatchArea::wheelEvent(QWheelEvent *event) {
190 if (!m_sw->m_resampledRaster || m_sw->m_lx == 0 || m_sw->m_ly == 0) return;
191
192 int step = event->delta() > 0 ? 120 : -120;
193 double factor = exp(0.001 * step);
194 if (factor == 1.0) return;
195 double scale = m_sw->m_viewAff.det();
196 double minZoom =
197 std::min((double)m_sw->m_lx / m_sw->m_resampledRaster->getLx(),
198 (double)m_sw->m_ly / m_sw->m_resampledRaster->getLy());
199 if ((factor < 1 && sqrt(scale) < minZoom) || (factor > 1 && scale > 1200.0))
200 return;
201
202 TPointD delta(event->pos().x(), height() - event->pos().y());
203 m_sw->m_viewAff =
204 (TTranslation(delta) * TScale(factor) * TTranslation(-delta)) *
205 m_sw->m_viewAff;
206
207 m_sw->m_leftSwatch->updateRaster();
208 m_sw->m_rightSwatch->updateRaster();
209 }
210
211 //-------------------------------------------------------------------------------
212
resizeEvent(QResizeEvent * event)213 void CleanupSwatch::resizeEvent(QResizeEvent *event) {
214 QSize s = m_leftSwatch->size();
215 m_lx = s.width();
216 m_ly = s.height();
217
218 // m_rightSwatch->resize(m_lx, m_ly);
219 m_leftSwatch->setMinimumHeight(0);
220 m_rightSwatch->setMinimumHeight(0);
221 m_leftSwatch->updateRaster();
222 m_rightSwatch->updateRaster();
223 // m_rightSwatch->updateRaster();
224 QWidget::resizeEvent(event);
225 // update();
226 }
227
228 /*
229 void CleanupSwatch::enableRightSwatch(bool state)
230 {
231 setVisible(state);
232 update();
233 }*/
234
235 //---------------------------------------------------
236
updateCleanupped(bool dragging)237 void CleanupSwatch::CleanupSwatchArea::updateCleanupped(bool dragging) {
238 TAffine aff = getFinalAff();
239
240 TRect rectToCompute = convert(aff.inv() * convert(m_r->getBounds()));
241 rectToCompute = rectToCompute.enlarge(
242 TCleanupper::instance()->getParameters()->m_despeckling);
243
244 TRect outRect = m_sw->m_resampledRaster->getBounds() * rectToCompute;
245 if (outRect.isEmpty()) return;
246
247 TRasterP rasCleanupped = TCleanupper::instance()->processColors(
248 m_sw->m_resampledRaster->extract(outRect));
249 TPointD cleanuppedPos = convert(outRect.getP00());
250
251 TRop::quickPut(m_r, rasCleanupped, aff * TTranslation(cleanuppedPos));
252 }
253
254 //---------------------------------------------------------------------------------
255 #ifdef LEVO
256
257 void CleanupSwatch::CleanupSwatchArea::updateCleanupped Versione ricalcolo Al
258 Release Del
mouse(bool dragging)259 mouse(bool dragging) {
260 TAffine aff = getFinalAff();
261
262 TRect rectToCompute = convert(aff.inv() * convert(m_r->getBounds()));
263 rectToCompute = rectToCompute.enlarge(
264 TCleanupper::instance()->getParameters()->m_despeckling);
265
266 TRect outRect = m_sw->m_resampledRaster->getBounds() * rectToCompute;
267 if (outRect.isEmpty()) return;
268
269 if (dragging && m_sw->m_lastRasCleanupped)
270 m_r->fill(TPixel(200, 200, 200));
271 else {
272 m_sw->m_lastRasCleanupped = TCleanupper::instance()->processColors(
273 m_sw->m_resampledRaster->extract(outRect));
274 m_sw->m_lastCleanuppedPos = convert(outRect.getP00());
275 }
276 TRop::quickPut(m_r, m_sw->m_lastRasCleanupped,
277 aff * TTranslation(m_sw->m_lastCleanuppedPos));
278 }
279 #endif
280
281 //---------------------------------------------------------------------------------
282
getFinalAff()283 TAffine CleanupSwatch::CleanupSwatchArea::getFinalAff() {
284 return m_sw->m_viewAff *
285 TAffine().place(m_sw->m_resampledRaster->getCenterD(),
286 m_r->getCenterD());
287 }
288
289 //------------------------------------------------------------------------------
updateRaster(bool dragging)290 void CleanupSwatch::CleanupSwatchArea::updateRaster(bool dragging) {
291 if (isHidden() || m_sw->m_lx == 0 || m_sw->m_ly == 0) return;
292
293 if (!m_r || m_r->getLx() != m_sw->m_lx || m_r->getLy() != m_sw->m_ly)
294 m_r = TRaster32P(m_sw->m_lx, m_sw->m_ly);
295
296 if (!m_sw->m_resampledRaster)
297 m_r->fill(TPixel(200, 200, 200));
298 else {
299 m_r->fill(TPixel::White);
300 if (m_isLeft)
301 TRop::quickPut(m_r, m_sw->m_origRaster,
302 getFinalAff() * m_sw->m_resampleAff);
303 else
304 updateCleanupped(dragging);
305 }
306 if (dragging)
307 repaint();
308 else
309 update();
310 }
311
312 //----------------------------------------------------------------------------------
313
paintEvent(QPaintEvent * event)314 void CleanupSwatch::CleanupSwatchArea::paintEvent(QPaintEvent *event) {
315 QPainter p(this);
316 if (!m_r)
317 p.fillRect(rect(), QBrush(QColor(200, 200, 200)));
318 else
319 p.drawImage(rect(), rasterToQImage(m_r));
320 }
321
322 //-----------------------------------------------------------------
323
isEnabled()324 bool CleanupSwatch::isEnabled() { return isVisible() && m_enabled; }
325
326 //------------------------------------------------------------
setRaster(TRasterP rasLeft,const TAffine & aff,TRasterP ras)327 void CleanupSwatch::setRaster(TRasterP rasLeft, const TAffine &aff,
328 TRasterP ras) {
329 if (!isVisible()) {
330 m_resampledRaster = TRasterP();
331 m_origRaster = TRasterP();
332 // m_lastRasCleanupped = TRasterP();
333 return;
334 }
335
336 m_resampledRaster = ras;
337 m_origRaster = rasLeft;
338 m_resampleAff = aff;
339
340 m_leftSwatch->updateRaster();
341 m_rightSwatch->updateRaster();
342 }
343
344 //--------------------------------------------------------------------
345
updateCleanupped()346 void CleanupSwatch::updateCleanupped() { m_rightSwatch->updateRaster(); }
347