1 //
2 // C++ Implementation: iview
3 //
4 // Description:
5 //
6 //
7 // Author: Pierre Marchand <pierremarc@oep-h.com>, (C) 2009
8 //
9 // Copyright: See COPYING file that comes with this distribution
10 //
11 //
12
13 #include "iview.h"
14
15 #include <QApplication>
16 #include <QMouseEvent>
17 #include <QScrollBar>
18 #include <QPolygonF>
19 #include <QDebug>
20
IView(QWidget * parent)21 IView::IView ( QWidget * parent )
22 :QGraphicsView ( parent )
23 {
24 curImage = 0;
25 m_controlRect = false;
26 setScene ( new QGraphicsScene );
27 setInteractive ( true );
28 theRect = QRect();
29 isSelecting = false;
30 isPanning = false;
31 setAlignment ( Qt::AlignTop | Qt::AlignHCenter );
32 setTransformationAnchor ( QGraphicsView::NoAnchor );
33 setRenderHint ( QPainter::Antialiasing, true );
34
35
36 curSel = scene()->addPolygon ( QPolygonF() ,QPen ( Qt::NoPen ), QColor ( 10,10,10,100 ) );
37 curSel->setZValue ( 1.0 );
38
39 QPen rctPen(Qt::blue, 2);
40 rctPen.setCosmetic(true);
41 curRect = scene()->addRect(QRect(),rctPen, QBrush(Qt::NoBrush));
42 curRect->setZValue(10.0);
43
44 QPen edgP(Qt::NoPen);
45 edgP.setCosmetic(true);
46 curTL = scene()->addEllipse(QRect(), edgP, Qt::red);
47 curTR = scene()->addEllipse(QRect(), edgP, Qt::red);
48 curBL = scene()->addEllipse(QRect(), edgP, Qt::red);
49 curBR = scene()->addEllipse(QRect(), edgP, Qt::red);
50
51 curTL->setZValue(100.0);
52 curTR->setZValue(100.0);
53 curBL->setZValue(100.0);
54 curBR->setZValue(100.0);
55
56 connect(this, SIGNAL(rectChange(QRect)), this, SLOT(drawSelRect(QRect)));
57 }
58
mouseMoveEvent(QMouseEvent * e)59 void IView::mouseMoveEvent ( QMouseEvent * e )
60 {
61 ////qDebug()<<"IView::mouseMoveEvent";
62 if ( isPanning )
63 {
64 QPointF pos ( e->pos() );
65 int vDelta ( qRound ( mouseStartPoint.y() - pos.y() ) );
66 int hDelta ( qRound ( mouseStartPoint.x() - pos.x() ) );
67 verticalScrollBar()->setValue ( verticalScrollBar()->value() + vDelta );
68 horizontalScrollBar()->setValue ( horizontalScrollBar()->value() + hDelta );
69 mouseStartPoint = pos;
70 return;
71 }
72 else
73 {
74 QPointF pressPoint(mapToScene ( e->pos() ));
75
76 QRectF rectTL(curTL->rect());
77 rectTL.translate(curRect->rect().topLeft());
78
79 QRectF rectTR(curTR->rect());
80 rectTR.translate(curRect->rect().topRight());
81
82 QRectF rectBR(curBR->rect());
83 rectBR.translate(curRect->rect().bottomRight());
84
85 QRectF rectBL(curBL->rect());
86 rectBL.translate(curRect->rect().bottomLeft());
87
88 if(rectTL.contains( pressPoint ))
89 {
90 QApplication::setOverrideCursor (Qt::SizeFDiagCursor);
91 }
92 else if(rectTR.contains( pressPoint ))
93 {
94 QApplication::setOverrideCursor (Qt::SizeBDiagCursor);
95 }
96 else if(rectBR.contains( pressPoint ))
97 {
98 QApplication::setOverrideCursor (Qt::SizeFDiagCursor);
99 }
100 else if(rectBL.contains( pressPoint ))
101 {
102 QApplication::setOverrideCursor (Qt::SizeBDiagCursor);
103 }
104 else
105 QApplication::restoreOverrideCursor();
106 }
107 if ( !isSelecting )
108 return;
109
110 if(m_controlRect)
111 {
112 QPointF mp(mapToScene ( e->pos() ));
113 {
114 QRectF r ( mouseStartPoint, mp );
115 theRect = r.normalized().toRect() ;
116 }
117 emit rectChange(theRect);
118 }
119 }
120
mousePressEvent(QMouseEvent * e)121 void IView::mousePressEvent ( QMouseEvent * e )
122 {
123 //qDebug()<<"IView::mousePressEvent";
124 if ( !scene() )
125 return;
126
127 if ( e->button() == Qt::MidButton )
128 {
129 mouseStartPoint = e->pos() ;
130 isPanning = true;
131 QApplication::setOverrideCursor ( QCursor ( Qt::ClosedHandCursor ) );
132 }
133 else
134 {
135 QPointF pressPoint(mapToScene ( e->pos() ));
136 if(!m_controlRect)
137 selectGlyph(pressPoint);
138 else
139 {
140 QRectF rectTL(curTL->rect());
141 rectTL.translate(curRect->rect().topLeft());
142
143 QRectF rectTR(curTR->rect());
144 rectTR.translate(curRect->rect().topRight());
145
146 QRectF rectBR(curBR->rect());
147 rectBR.translate(curRect->rect().bottomRight());
148
149 QRectF rectBL(curBL->rect());
150 rectBL.translate(curRect->rect().bottomLeft());
151
152 if(rectTL.contains( pressPoint ))
153 {
154 mouseStartPoint = curRect->rect().bottomRight();
155 }
156 else if(rectTR.contains( pressPoint ))
157 {
158 mouseStartPoint = curRect->rect().bottomLeft();
159 }
160 else if(rectBR.contains( pressPoint ))
161 {
162 mouseStartPoint = curRect->rect().topLeft();
163 }
164 else if(rectBL.contains( pressPoint ))
165 {
166 mouseStartPoint = curRect->rect().topRight();
167 }
168 else
169 mouseStartPoint = pressPoint;
170 }
171 isSelecting = true;
172 }
173 }
174
mouseReleaseEvent(QMouseEvent * e)175 void IView::mouseReleaseEvent ( QMouseEvent * e )
176 {
177 //qDebug()<<"IView::mouseReleaseEvent";
178 if ( isPanning )
179 {
180 isPanning = false;
181 QApplication::restoreOverrideCursor();
182 return;
183 }
184 if ( !isSelecting )
185 return;
186
187 isSelecting = false;
188 // theRect = QRect();
189
190 }
191
setImage(const QString & path)192 void IView::setImage ( const QString & path )
193 {
194 //qDebug()<<"IView::setImage";
195 if ( curImage )
196 {
197 delete curImage;
198 curImage = 0;
199 }
200
201
202 QImage i ( path );
203 if ( i.isNull() )
204 return;
205
206 curImage = scene()->addPixmap ( QPixmap::fromImage ( i ) );
207 fitImage();
208
209 drawSelRect(QRect());
210 }
211
setImage(const QPixmap & pixmap)212 void IView::setImage(const QPixmap & pixmap)
213 {
214 //qDebug()<<"IView::setImage";
215 if ( curImage )
216 {
217 delete curImage;
218 curImage = 0;
219 }
220
221 curImage = scene()->addPixmap ( pixmap );
222 fitImage();
223
224 drawSelRect(QRect());
225 }
226
getPixmap()227 QPixmap IView::getPixmap()
228 {
229 //qDebug()<<"IView::getPixmap";
230 if ( curImage )
231 {
232 return curImage->pixmap();
233 }
234 return QPixmap();
235 }
236
237
drawSelRect(QRect r)238 void IView::drawSelRect(QRect r)
239 {
240 //qDebug()<<"IView::drawSelRect";
241 if(r.isNull())
242 {
243 curSel->setPolygon ( QPolygonF() );
244
245 curRect->setRect(QRect());
246
247 curTL->setRect(QRect());
248 curTR->setRect(QRect());
249 curBR->setRect(QRect());
250 curBL->setRect(QRect());
251
252 return;
253
254 }
255
256 // mask
257 QPolygonF p;
258 QRect ir(curImage->boundingRect().toRect());
259 p << ir.topLeft() << ir.topRight() << ir.bottomRight() << ir.bottomLeft() << ir.topLeft() ;
260 p << r.topLeft() << r.bottomLeft() << r.bottomRight() << r.topRight()<< r.topLeft() ;
261 curSel->setPolygon (p);
262
263 // rect
264 curRect->setRect(r);
265
266
267 // edges
268 if(m_controlRect)
269 {
270 QRectF baseR(-4,-4,8,8);
271 QTransform t;
272 double hs(transform().m11());
273 double vs(transform().m22());
274 t.scale(1.0 / hs, 1.0 / vs);
275 baseR = t.mapRect(baseR);
276
277 curTL->setRect(baseR);
278 curTR->setRect(baseR);
279 curBR->setRect(baseR);
280 curBL->setRect(baseR);
281
282 curTL->setPos(r.topLeft());
283 curTR->setPos(r.topRight());
284 curBL->setPos(r.bottomLeft());
285 curBR->setPos(r.bottomRight());
286 }
287
288
289 }
290
291
fitImage()292 void IView::fitImage()
293 {
294 //qDebug()<<"IView::fitImage";
295 if(!curImage)
296 return;
297
298 double wR = width() /curImage->boundingRect().width() ;
299 double hR = height()/ curImage->boundingRect().height();
300
301 double R = (wR > hR) ? hR : wR;
302 QTransform T;
303 T.scale(R,R);
304 setTransform( T , false);
305
306 }
307
resizeEvent(QResizeEvent * event)308 void IView::resizeEvent(QResizeEvent * event)
309 {
310 //qDebug()<<"View::resizeEvent";
311 fitImage();
312 }
313
selectGlyph(const QPointF & scenepos)314 void IView::selectGlyph(const QPointF & scenepos)
315 {
316 //qDebug()<<"IView::selectGlyph";
317 // const unsigned int treshold (5);
318 if(!curImage)
319 return;
320
321 QPoint imgp(curImage->mapFromScene(scenepos).toPoint());
322 QImage cImg(curImage->pixmap().toImage());
323 QRgb ref(cImg.pixel(imgp));
324
325
326 // crop it
327 QRect r;
328 const int cw = cImg.width();
329 const int ch = cImg.height();
330 bool topReached(false);
331 for(int y(0); y < ch; ++y)
332 {
333
334 for(int x(0);x < cw; ++x)
335 {
336 if(cImg.pixel(x,y) == ref)
337 {
338 topReached = true;
339 r.setTop(y);
340 break;
341 }
342 }
343 if(topReached)
344 break;
345 }
346 bool bottomReached(false);
347 for(int y(ch - 1); y >= 0; --y)
348 {
349
350 for(int x(cw-1);x >=0; --x)
351 {
352 if(cImg.pixel(x,y) == ref)
353 {
354 bottomReached = true;
355 r.setBottom(y);
356 break;
357 }
358 }
359 if(bottomReached)
360 break;
361 }
362 r.setLeft(cw);
363 for(int y(0); y < ch; ++y)
364 {
365
366 for(int x(0);x < cw; ++x)
367 {
368 if(cImg.pixel(x,y) == ref)
369 {
370 r.setLeft(qMin(x,r.left()));
371 break;
372 }
373 }
374 }
375 r.setRight(0);
376 for(int y(0); y < ch; ++y)
377 {
378
379 for(int x(cw -1);x >= 0; --x)
380 {
381 if(cImg.pixel(x,y) == ref)
382 {
383 r.setRight(qMax(x,r.right()));
384 break;
385 }
386 }
387 }
388 //qDebug()<<"R"<<r.top()<<r.right()<<r.bottom()<<r.left();
389 theRect = r;
390 emit selColorChanged(ref);
391 emit rectChange(theRect);
392 // drawSelRect(r);
393 }
394
setControlRect(bool u)395 void IView::setControlRect(bool u)
396 {
397 //qDebug()<<"IView::setControlRect";
398 m_controlRect = u;
399 if (u)
400 {
401 //qDebug()<<"CR"<<theRect;
402 emit rectChange(theRect);
403 }
404 else
405 {
406 curTL->setRect(QRect());
407 curTR->setRect(QRect());
408 curBR->setRect(QRect());
409 curBL->setRect(QRect());
410 }
411 }
412
413