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