1 /***************************************************************************
2 kmagview.cpp - description
4 begin : Mon Feb 12 23:45:41 EST 2001
5 copyright : (C) 2001-2003 by Sarang Lakare
6 email : sarang#users.sourceforge.net
7 copyright : (C) 2003-2004 by Olaf Schmidt
8 email : ojschmidt@kde.org
9 copyright : (C) 2008 by Matthew Woehlke
10 email : mw_triad@users.sourceforge.net
11 ***************************************************************************/
13 /***************************************************************************
15 * This program is free software; you can redistribute it and/or modify *
16 * it under the terms of the GNU General Public License as published by *
17 * the Free Software Foundation; either version 2 of the License, or *
18 * (at your option) any later version. *
20 ***************************************************************************/
23 // application specific includes
24 #include "kmagzoomview.h"
25 #include "kmagzoomview.moc"
28 // include files for Qt
29 #include <QtGui/QBitmap>
30 #include <QtGui/QCursor>
31 #include <QtCore/qglobal.h>
32 #include <QtGui/QPainter>
33 #include <QtGui/QWidget>
34 #include <QtGui/QPixmap>
35 #include <QtGui/QFocusEvent>
36 #include <QtGui/QHideEvent>
37 #include <QtGui/QKeyEvent>
38 #include <QtGui/QShowEvent>
39 #include <QtGui/QResizeEvent>
40 #include <QtGui/QMouseEvent>
41 #include <QtGui/QDesktopWidget>
43 // include files for KDE
44 #include <kapplication.h>
49 // include bitmaps for cursors
50 static uchar left_ptr_bits
[] = {
51 0x00, 0x00, 0x08, 0x00, 0x18, 0x00, 0x38, 0x00, 0x78, 0x00, 0xf8, 0x00,
52 0xf8, 0x01, 0xf8, 0x03, 0xf8, 0x07, 0xf8, 0x00, 0xd8, 0x00, 0x88, 0x01,
53 0x80, 0x01, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00};
55 static uchar left_ptrmsk_bits
[] = {
56 0x0c, 0x00, 0x1c, 0x00, 0x3c, 0x00, 0x7c, 0x00, 0xfc, 0x00, 0xfc, 0x01,
57 0xfc, 0x03, 0xfc, 0x07, 0xfc, 0x0f, 0xfc, 0x0f, 0xfc, 0x01, 0xdc, 0x03,
58 0xcc, 0x03, 0x80, 0x07, 0x80, 0x07, 0x00, 0x03};
60 static uchar phand_bits
[] = {
61 0x00, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00,
62 0x7e, 0x04, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x70, 0x08, 0x00, 0x00,
63 0x08, 0x08, 0x00, 0x00, 0x70, 0x14, 0x00, 0x00, 0x08, 0x22, 0x00, 0x00,
64 0x30, 0x41, 0x00, 0x00, 0xc0, 0x20, 0x00, 0x00, 0x40, 0x12, 0x00, 0x00,
65 0x80, 0x08, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
66 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
67 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
68 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
69 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
70 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
71 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
72 static uchar phandm_bits
[] = {
73 0xfe, 0x01, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00,
74 0xff, 0x0f, 0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00, 0xf8, 0x1f, 0x00, 0x00,
75 0xfc, 0x1f, 0x00, 0x00, 0xf8, 0x3f, 0x00, 0x00, 0xfc, 0x7f, 0x00, 0x00,
76 0xf8, 0xff, 0x00, 0x00, 0xf0, 0x7f, 0x00, 0x00, 0xe0, 0x3f, 0x00, 0x00,
77 0xc0, 0x1f, 0x00, 0x00, 0x80, 0x0f, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
78 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
79 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
80 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
81 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
82 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
83 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
86 KMagZoomView::KMagZoomView(QWidget
*parent
, const char *name
)
87 : Q3ScrollView(parent
, name
),
88 m_selRect(0, 0, 128, 128, this),
90 m_mouseViewTimer(parent
),
91 m_latestCursorPos(0,0),
98 KApplication::setGlobalMouseTracking(true);
99 viewport()->setMouseTracking(true);
100 viewport()->setBackgroundMode (Qt::NoBackground
);
101 viewport()->setFocusPolicy(Qt::StrongFocus
);
103 // init the zoom matrix
104 m_zoomMatrix
.reset();
105 m_zoomMatrix
.scale(m_zoom
, m_zoom
);
106 m_zoomMatrix
.rotate(m_rotation
);
108 m_ctrlKeyPressed
= false;
109 m_shiftKeyPressed
= false;
110 m_refreshSwitch
= true;
111 m_refreshSwitchStateOnHide
= m_refreshSwitch
;
113 // set the refresh rate
116 // connect it to grabFrame()
117 connect(&m_grabTimer
, SIGNAL(timeout()), SLOT(grabFrame()));
118 // start the grabTimer
119 m_grabTimer
.start(static_cast<int>(1000.0/m_fps
));
121 // connect it to updateMouseView()
122 connect(&m_mouseViewTimer
, SIGNAL(timeout()), SLOT(updateMouseView()));
123 // start the grabTimer @ 25 frames per second!
124 m_mouseViewTimer
.start(25);
126 this->setWhatsThis( i18n("This is the main window which shows the contents of the\
127 selected region. The contents will be magnified according to the zoom level that is set."));
129 // different ways to show the cursor.
130 m_showMouseTypes
<< "Hidden" << "Box" << "Arrow" << "Actual";
136 KMagZoomView::~KMagZoomView()
138 KApplication::setGlobalMouseTracking(true);
142 * This function will set/reset mouse following of grab window.
144 void KMagZoomView::followMouse(bool follow
)
147 m_followMouse
= true;
148 m_mouseMode
= Normal
;
149 setVScrollBarMode (Q3ScrollView::AlwaysOff
);
150 setHScrollBarMode (Q3ScrollView::AlwaysOff
);
152 m_followMouse
= false;
153 m_mouseMode
= Normal
;
154 setVScrollBarMode (Q3ScrollView::AlwaysOn
);
155 setHScrollBarMode (Q3ScrollView::AlwaysOn
);
160 * Called when the widget is hidden. Stop refresh when this happens.
162 void KMagZoomView::hideEvent( QHideEvent
* )
164 // Save the state of the refresh switch.. the state will be restored
165 // when showEvent is called
166 m_refreshSwitchStateOnHide
= m_refreshSwitch
;
168 // Check if refresh is ON
169 if(m_refreshSwitch
) {
176 * Called when the widget is shown. Start refresh when this happens.
178 void KMagZoomView::showEvent( QShowEvent
* )
180 // Check if refresh switch was ON when hide was called and if currently it is OFF
181 if(m_refreshSwitchStateOnHide
&& !m_refreshSwitch
) {
182 // start the refresh in that case
188 * Called when the widget is resized. Check if fitToWindow is active when this happens.
190 void KMagZoomView::resizeEvent( QResizeEvent
* e
)
192 Q3ScrollView::resizeEvent (e
);
198 * Called when the widget is to be repainted.
202 void KMagZoomView::drawContents ( QPainter
* p
, int clipx
, int clipy
, int clipw
, int cliph
)
204 if(m_zoomedPixmap
.isNull())
207 // Paint empty areas Qt::black
208 if (contentsX()+contentsWidth() < visibleWidth())
210 QRect (contentsX()+contentsWidth(), clipy
, visibleWidth()-contentsX()-contentsWidth(), cliph
)
211 & QRect (clipx
, clipy
, clipw
, cliph
),
213 if (contentsY()+contentsHeight() < visibleHeight())
215 QRect (clipx
, contentsY()+contentsHeight(), clipw
, visibleHeight()-contentsY()-contentsHeight())
216 & QRect (clipx
, clipy
, clipw
, cliph
),
219 // A pixmap which will be eventually displayed
222 // Get mouse position relative to the image
223 QPoint mousePos
= calcMousePos (m_refreshSwitch
);
225 // show the pixel under mouse cursor
228 // Pixmap which will have the zoomed pixmap + mouse
229 zoomView
= new QPixmap(m_zoomedPixmap
);
231 // paint the mouse cursor
232 paintMouseCursor(zoomView
, mousePos
);
233 } else { // do not show mouse
234 zoomView
= &m_zoomedPixmap
;
237 // bitBlt this part on to the widget.
238 bitBlt(viewport(), QPoint (clipx
-contentsX(), clipy
-contentsY()), zoomView
, QRect(clipx
, clipy
, clipw
, cliph
));
240 if(zoomView
!= &m_zoomedPixmap
)
245 * Draws the mouse cursor according to the current selection of the type of
246 * mouse cursor to draw.
248 void KMagZoomView::paintMouseCursor(QPaintDevice
*dev
, const QPoint
&mousePos
)
253 // painter for the zoom view
256 if(m_latestCursorPos
.x() >= 0 && m_latestCursorPos
.x() < m_selRect
.width() &&
257 m_latestCursorPos
.y() >= 0 && m_latestCursorPos
.y() < m_selRect
.height() ) { // || updateMousePos) {
258 // mouse position is indeed inside the selRect
260 // How to show the mouse :
262 switch(m_showMouse
) {
264 // 1. Square around the pixel
265 pz
.setPen(Qt::white
);
267 #warning "Port Qt4 pz.setRasterOp(Qt::XorROP);";
269 //pz.setRasterOp(Qt::XorROP);
270 pz
.drawRect(mousePos
.x()-1, mousePos
.y()-1, (int)m_zoom
+2, (int)m_zoom
+2);
276 pz
.setPen(Qt::black
);
277 pz
.setBackgroundColor(Qt::white
);
279 QBitmap sCursor
= QBitmap::fromData( QSize(16, 16), left_ptr_bits
);
280 QBitmap mask
= QBitmap::fromData( QSize(16, 16), left_ptrmsk_bits
);
281 sCursor
.setMask(mask
);
282 sCursor
= sCursor
.transformed(m_zoomMatrix
);
284 // since hot spot is at 3,1
286 pz
.drawPixmap(mousePos
.x()-(int)(3.0*m_zoom
), mousePos
.y()-(int)m_zoom
, sCursor
);
287 else if (m_rotation
== 90)
288 pz
.drawPixmap(mousePos
.x()-(int)(16.0*m_zoom
), mousePos
.y()-(int)(3.0*m_zoom
), sCursor
);
289 else if (m_rotation
== 180)
290 pz
.drawPixmap(mousePos
.x()-(int)(13.0*m_zoom
), mousePos
.y()-(int)(16.0*m_zoom
), sCursor
);
291 else if (m_rotation
== 270)
292 pz
.drawPixmap(mousePos
.x()-(int)m_zoom
, mousePos
.y()-(int)(13.0*m_zoom
), sCursor
);
299 // Get the current cursor type
300 QWidget
*dummy
= KApplication::topLevelAt(QCursor::pos());
303 kDebug() << ">" << dummy
->name() << ":" << dummy
->cursor().shape() << "-";
304 switch(this->cursor().shape()) {
305 case Qt::ArrowCursor
:
308 pz
.setPen(Qt::black
);
309 pz
.setBackgroundColor(Qt::white
);
311 QBitmap sCursor
= QBitmap::fromData( QSize(16, 16), left_ptr_bits
);
312 QBitmap mask
= QBitmap::fromData( QSize(16, 16), left_ptrmsk_bits
);
313 sCursor
.setMask(mask
);
314 sCursor
= sCursor
.transformed(m_zoomMatrix
);
316 // since hot spot is at 3,1
317 pz
.drawPixmap(mousePos
.x()-(int)(3.0*m_zoom
), mousePos
.y()-(int)m_zoom
, sCursor
);
321 QBitmap sCursor
= QBitmap::fromData( QSize(32, 32), phand_bits
);
322 QBitmap mask
= QBitmap::fromData( QSize(32, 32), phandm_bits
);
323 sCursor
.setMask(mask
);
325 pz
.drawPixmap(mousePos
.x(), mousePos
.y(), sCursor
);
334 // do not show anything
336 } // switch(m_showMouse)
341 QPoint
KMagZoomView::calcMousePos(bool updateMousePos
)
343 // get position of mouse wrt selRect
344 if(updateMousePos
) { // get a new position only if asked
345 m_latestCursorPos
= QCursor::pos();
346 m_latestCursorPos
-= QPoint(m_selRect
.x(), m_selRect
.y());
349 // get coordinates of the pixel w.r.t. the zoomed pixmap
350 if (m_rotation
== 90)
351 return QPoint ((int)((float)(m_selRect
.height()-m_latestCursorPos
.y())*m_zoom
),
352 (int)((float)m_latestCursorPos
.x()*m_zoom
));
353 else if (m_rotation
== 180)
354 return QPoint ((int)((float)(m_selRect
.width()-m_latestCursorPos
.x())*m_zoom
),
355 (int)((float)(m_selRect
.height()-m_latestCursorPos
.y())*m_zoom
));
356 else if (m_rotation
== 270)
357 return QPoint ((int)((float)m_latestCursorPos
.y()*m_zoom
),
358 (int)((float)(m_selRect
.width()-m_latestCursorPos
.x())*m_zoom
));
360 return QPoint ((int)((float)m_latestCursorPos
.x()*m_zoom
),
361 (int)((float)m_latestCursorPos
.y()*m_zoom
));
368 * Called when mouse is clicked inside the window.
372 void KMagZoomView::mousePressEvent(QMouseEvent
*e
)
374 switch(e
->button()) {
375 case Qt::LeftButton
:
376 if(m_ctrlKeyPressed
) {
377 // check if currently in resize mode
378 // don't do anything if fitToWindow is enabled
379 if ((m_mouseMode
!= ResizeSelection
) && !m_fitToWindow
) {
380 // set the mode to ResizeSelection
381 m_mouseMode
= ResizeSelection
;
383 // set mouse cursor to "resize all direction"
384 setCursor(Qt::SizeAllCursor
);
386 // backup the old position
387 m_oldMousePos
.setX(e
->globalX());
388 m_oldMousePos
.setY(e
->globalY());
390 // set the cursor position to the bottom-right of the selected region
391 QCursor::setPos(m_selRect
.bottomRight());
393 // show the selection rectangle
397 // ignore this button press.. so it goes to the parent
400 } else if(m_shiftKeyPressed
) {
401 // check if currently in move mode
402 // don't do anything if follow mouse is enabled
403 if ((m_mouseMode
!= MoveSelection
) && !m_followMouse
) {
404 m_mouseMode
= MoveSelection
;
406 // set mouse cursor to cross hair
407 setCursor(Qt::CrossCursor
);
409 // backup the old position
410 m_oldMousePos
.setX(e
->globalX());
411 m_oldMousePos
.setY(e
->globalY());
413 // set the cursor position to the center of the selected region
414 QCursor::setPos(m_selRect
.center());
416 // show the selected rectangle
420 // ignore this button press.. so it goes to the parent
424 // check if currently in move mode
425 // don't do anything if follow mouse is enabled
426 if ((m_mouseMode
!= GrabSelection
) && !m_followMouse
) {
427 m_mouseMode
= GrabSelection
;
429 // set mouse cursor to hand
430 setCursor(Qt::PointingHandCursor
);
432 // store the old position
433 m_oldMousePos
.setX(e
->globalX());
434 m_oldMousePos
.setY(e
->globalY());
436 m_oldCenter
= m_selRect
.center();
438 // show the selected rectangle
442 // ignore this button press.. so it goes to the parent
449 // check if currently in move mode
450 // don't do anything if follow mouse is enabled
451 if ((m_mouseMode
!= MoveSelection
) && !m_followMouse
) {
452 m_mouseMode
= MoveSelection
;
454 // set mouse cursor to cross hair
455 setCursor(Qt::CrossCursor
);
457 // backup the old position
458 m_oldMousePos
.setX(e
->globalX());
459 m_oldMousePos
.setY(e
->globalY());
461 // set the cursor position to the center of the selected region
462 QCursor::setPos(m_selRect
.center());
464 // show the selected rectangle
468 // ignore this button press.. so it goes to the parent
474 // ignore this button press.. so it goes to the parent
482 * Called when a mouse button is released
486 void KMagZoomView::mouseReleaseEvent(QMouseEvent
*e
)
488 switch(e
->button()) {
489 case Qt::LeftButton
:
491 // check if currently in move mode
492 if(m_mouseMode
== MoveSelection
) {
493 // hide the selection window
495 // set the mouse mode to normal
496 m_mouseMode
= Normal
;
498 // restore the cursor shape
499 setCursor(Qt::ArrowCursor
);
501 // restore the cursor position
502 QCursor::setPos(m_oldMousePos
);
503 } else if(m_mouseMode
== ResizeSelection
) {
504 // hide the selection window
506 // set the mouse mode to normal
507 m_mouseMode
= Normal
;
509 // restore the cursor shape
510 setCursor(Qt::ArrowCursor
);
512 // restore the cursor position
513 QCursor::setPos(m_oldMousePos
);
514 } else if(m_mouseMode
== GrabSelection
) {
515 // hide the selection window
518 // set the mouse mode to normal
519 m_mouseMode
= Normal
;
521 // restore the cursor shape
522 setCursor(Qt::ArrowCursor
);
526 case Qt::RightButton
:
539 * Called when mouse is moved inside the window
543 void KMagZoomView::mouseMoveEvent(QMouseEvent
*e
)
545 if(m_mouseMode
== ResizeSelection
) {
546 // In resize selection mode
547 // set the current mouse position as the bottom, right corner
548 m_selRect
.setRight(e
->globalX());
549 m_selRect
.setBottom(e
->globalY());
552 } else if(m_mouseMode
== MoveSelection
) {
555 // set new center to be the current mouse position
556 newCenter
= e
->globalPos();
558 // make sure the mouse position is not taking the grab window outside
560 if(newCenter
.x() < m_selRect
.width()/2) {
561 // set X to the minimum possible X
562 newCenter
.setX(m_selRect
.width()/2);
563 } else if(newCenter
.x() >= QApplication::desktop()->width()-m_selRect
.width()/2) {
564 // set X to the maximum possible X
565 newCenter
.setX(QApplication::desktop()->width()-m_selRect
.width()/2-1);
568 if(newCenter
.y() < m_selRect
.height()/2) {
569 // set Y to the minimum possible Y
570 newCenter
.setY(m_selRect
.height()/2);
571 } else if(newCenter
.y() >= QApplication::desktop()->height()-m_selRect
.height()/2) {
572 // set Y to the maximum possible Y
573 newCenter
.setY(QApplication::desktop()->height()-m_selRect
.height()/2-1);
575 // move to the new center
576 m_selRect
.moveCenter(newCenter
);
577 // update the grab rectangle display
580 } else if(m_mouseMode
== GrabSelection
) {
584 newPos
= e
->globalPos();
586 QPoint delta
= (newPos
- m_oldMousePos
)/m_zoom
;
587 QPoint newCenter
= m_oldCenter
-delta
;
589 // make sure the mouse position is not taking the grab window outside
591 if(newCenter
.x() < m_selRect
.width()/2) {
592 // set X to the minimum possible X
593 newCenter
.setX(m_selRect
.width()/2);
594 } else if(newCenter
.x() >= QApplication::desktop()->width()-m_selRect
.width()/2) {
595 // set X to the maximum possible X
596 newCenter
.setX(QApplication::desktop()->width()-m_selRect
.width()/2-1);
599 if(newCenter
.y() < m_selRect
.height()/2) {
600 // set Y to the minimum possible Y
601 newCenter
.setY(m_selRect
.height()/2);
602 } else if(newCenter
.y() >= QApplication::desktop()->height()-m_selRect
.height()/2) {
603 // set Y to the maximum possible Y
604 newCenter
.setY(QApplication::desktop()->height()-m_selRect
.height()/2-1);
607 // move to the new center
608 m_selRect
.moveCenter(newCenter
);
609 // update the grab rectangle display
615 void KMagZoomView::keyPressEvent(QKeyEvent
*e
)
618 if (e
->state() & Qt::ShiftModifier
)
621 if (e
->key() == Qt::Key_Control
)
622 m_ctrlKeyPressed
= true;
623 else if (e
->key() == Qt::Key_Shift
)
624 m_shiftKeyPressed
= true;
625 else if (e
->key() == Qt::Key_Left
)
627 if (e
->state() & Qt::ControlModifier
)
629 if (offset
>= m_selRect
.width())
630 m_selRect
.setWidth (1);
632 m_selRect
.setWidth (m_selRect
.width()-offset
);
634 else if (contentsX() > 0)
636 offset
= (int)(offset
*m_zoom
);
637 if (contentsX() > offset
)
638 setContentsPos (contentsX()-offset
, contentsY());
640 setContentsPos (0, contentsY());
642 else if (m_followMouse
== false)
644 if (offset
> m_selRect
.x())
647 m_selRect
.translate (-offset
,0);
651 else if (e
->key() == Qt::Key_Right
)
653 if (e
->state() & Qt::ControlModifier
)
655 if (m_selRect
.right()+offset
>= QApplication::desktop()->width())
656 m_selRect
.setRight (QApplication::desktop()->width()-1);
658 m_selRect
.setRight (m_selRect
.right()+offset
);
660 else if (contentsX() < contentsWidth()-visibleWidth())
662 offset
= (int)(offset
*m_zoom
);
663 if (contentsX()+offset
< contentsWidth()-visibleWidth())
664 setContentsPos (contentsX()+offset
, contentsY());
666 setContentsPos (contentsWidth()-visibleWidth(), contentsY());
668 else if (m_followMouse
== false)
670 if (m_selRect
.right()+offset
>= QApplication::desktop()->width())
671 m_selRect
.moveTopRight (QPoint (QApplication::desktop()->width()-1, m_selRect
.top()));
673 m_selRect
.translate (offset
,0);
677 else if (e
->key() == Qt::Key_Up
)
679 if (e
->state() & Qt::ControlModifier
)
681 if (offset
>= m_selRect
.height())
682 m_selRect
.setHeight (1);
684 m_selRect
.setHeight (m_selRect
.height()-offset
);
686 else if (contentsY() > 0)
688 offset
= (int)(offset
*m_zoom
);
689 if (contentsY() > offset
)
690 setContentsPos (contentsX(), contentsY()-offset
);
692 setContentsPos (contentsX(), 0);
694 else if (m_followMouse
== false)
696 if (offset
> m_selRect
.y())
699 m_selRect
.translate (0, -offset
);
703 else if (e
->key() == Qt::Key_Down
)
705 if (e
->state() & Qt::ControlModifier
)
707 if (m_selRect
.bottom()+offset
>= QApplication::desktop()->height())
708 m_selRect
.setBottom (QApplication::desktop()->height()-1);
710 m_selRect
.setBottom (m_selRect
.bottom()+offset
);
712 else if (contentsY() < contentsHeight()-visibleHeight())
714 offset
= (int)(offset
*m_zoom
);
715 if (contentsY()+offset
< contentsHeight()-visibleHeight())
716 setContentsPos (contentsX(), contentsY()+offset
);
718 setContentsPos (contentsX(), contentsHeight()-visibleHeight());
720 else if (m_followMouse
== false)
722 if (m_selRect
.bottom()+offset
>= QApplication::desktop()->height())
723 m_selRect
.moveBottomLeft (QPoint (m_selRect
.left(), QApplication::desktop()->height()-1));
725 m_selRect
.translate (0, offset
);
733 void KMagZoomView::keyReleaseEvent(QKeyEvent
*e
)
735 if (e
->key() == Qt::Key_Control
)
736 m_ctrlKeyPressed
= false;
737 else if (e
->key() == Qt::Key_Shift
)
738 m_shiftKeyPressed
= false;
743 void KMagZoomView::focusOutEvent(QFocusEvent
*e
)
745 if(e
->lostFocus() == true) {
746 m_ctrlKeyPressed
= false;
747 m_shiftKeyPressed
= false;
754 * This will fit the zoom view to the view window, thus using the maximum
755 * possible space in the window.
757 void KMagZoomView::fitToWindow()
759 unsigned int newWidth
, newHeight
;
761 // this is a temporary solution, cast, maybe newWidth and newHeight should be float
762 if ((m_rotation
== 90) || (m_rotation
== 270))
764 newWidth
= static_cast<unsigned int>(visibleHeight()/m_zoom
);
765 newHeight
= static_cast<unsigned int>(visibleWidth()/m_zoom
);
767 newWidth
= static_cast<unsigned int>(visibleWidth()/m_zoom
);
768 newHeight
= static_cast<unsigned int>(visibleHeight()/m_zoom
);
771 QPoint currCenter
= m_selRect
.center();
773 m_selRect
.setWidth(newWidth
);
774 m_selRect
.setHeight(newHeight
);
776 // make sure the selection window does not go outside of the display
777 if(currCenter
.x() < m_selRect
.width()/2) {
778 // set X to the minimum possible X
779 currCenter
.setX(m_selRect
.width()/2);
780 } else if(currCenter
.x() >= QApplication::desktop()->width()-m_selRect
.width()/2) {
781 // set X to the maximum possible X
782 currCenter
.setX(QApplication::desktop()->width()-m_selRect
.width()/2-1);
785 if(currCenter
.y() < m_selRect
.height()/2) {
786 // set Y to the minimum possible Y
787 currCenter
.setY(m_selRect
.height()/2);
788 } else if(currCenter
.y() >= QApplication::desktop()->height()-m_selRect
.height()/2) {
789 // set Y to the maximum possible Y
790 currCenter
.setY(QApplication::desktop()->height()-m_selRect
.height()/2-1);
793 m_selRect
.moveCenter(currCenter
);
794 // update the grab rectangle display
796 // m_fitToWindow = true;
797 viewport()->repaint(false);
800 void KMagZoomView::setFitToWindow(bool fit
)
811 void KMagZoomView::grabFrame()
813 // check refresh status
814 if (!m_refreshSwitch
)
817 // check if follow-mouse is enabled
818 if(m_followMouse
&& (m_mouseMode
!= ResizeSelection
)) {
819 // in this case grab w.r.t the current mouse position
822 // set new center to be the current mouse position
823 newCenter
= QCursor::pos();
825 // make sure the mouse position is not taking the grab window outside
827 if(newCenter
.x() < m_selRect
.width()/2) {
828 // set X to the minimum possible X
829 newCenter
.setX(m_selRect
.width()/2);
830 } else if(newCenter
.x() >= QApplication::desktop()->width()-m_selRect
.width()/2) {
831 // set X to the maximum possible X
832 newCenter
.setX(QApplication::desktop()->width()-m_selRect
.width()/2-1);
835 if(newCenter
.y() < m_selRect
.height()/2) {
836 // set Y to the minimum possible Y
837 newCenter
.setY(m_selRect
.height()/2);
838 } else if(newCenter
.y() >= QApplication::desktop()->height()-m_selRect
.height()/2) {
839 // set Y to the maximum possible Y
840 newCenter
.setY(QApplication::desktop()->height()-m_selRect
.height()/2-1);
842 // move to the new center
843 m_selRect
.moveCenter(newCenter
);
845 // update the grab rectangle display
849 //QRect r = pixmapRect();
851 // define a normalized rectangle
852 QRect selRect
= m_selRect
.normalized();
854 // grab screenshot from the screen and put it in the pixmap
855 m_grabbedPixmap
= QPixmap::grabWindow(QApplication::desktop()->winId(), selRect
.x(), selRect
.y(),
856 selRect
.width(), selRect
.height());
858 // colorize the grabbed pixmap, if applicable - TODO
859 if (m_colormode
== 0)
860 m_coloredPixmap
= m_grabbedPixmap
;
862 m_coloredPixmap
= ColorSim::recolor(m_grabbedPixmap
, m_colormode
);
865 m_zoomedPixmap
= m_coloredPixmap
.transformed(m_zoomMatrix
);
867 // call repaint to display the newly grabbed image
868 resizeContents (m_zoomedPixmap
.width(), m_zoomedPixmap
.height());
869 viewport()->repaint(false);
874 * Updates the mouse cursor in the zoom view.
876 void KMagZoomView::updateMouseView()
878 QPoint
pos(QCursor::pos());
879 if(m_selRect
.left() <= pos
.x() && pos
.x() <= m_selRect
.right() &&
880 m_selRect
.top() <= pos
.y() && pos
.y() <= m_selRect
.bottom() &&
882 viewport()->repaint(false);
886 * Toggles the state of refreshing.
888 void KMagZoomView::toggleRefresh()
890 if(m_refreshSwitch
) {
891 m_refreshSwitch
= false;
893 m_mouseViewTimer
.stop();
895 m_refreshSwitch
= true;
896 m_grabTimer
.start(1000/m_fps
);
897 m_mouseViewTimer
.start(40);
902 * This function sets the zoom value to be used.
904 void KMagZoomView::setZoom(float zoom
)
909 // update selection window size when zooming in if necessary
913 // recompute the zoom matrix
914 m_zoomMatrix
.reset();
915 m_zoomMatrix
.scale(m_zoom
, m_zoom
);
916 m_zoomMatrix
.rotate(m_rotation
);
918 m_zoomedPixmap
= m_coloredPixmap
.transformed(m_zoomMatrix
);
920 viewport()->repaint();
924 * This function sets the rotation value to be used.
926 void KMagZoomView::setRotation(int rotation
)
929 m_rotation
= rotation
;
931 // update selection window size if necessary
935 // recompute the zoom matrix
936 m_zoomMatrix
.reset();
937 m_zoomMatrix
.scale(m_zoom
, m_zoom
);
938 m_zoomMatrix
.rotate(m_rotation
);
940 m_zoomedPixmap
= m_coloredPixmap
.transformed(m_zoomMatrix
);
942 viewport()->repaint();
946 * Set a new color simulation mode.
948 void KMagZoomView::setColorMode(int mode
)
950 if (m_colormode
!= mode
) {
952 viewport()->repaint();
957 * Set a new refresh rate.
959 void KMagZoomView::setRefreshRate(float fps
)
963 m_fps
= static_cast<unsigned int>(fps
);
965 if(m_grabTimer
.isActive())
966 m_grabTimer
.start(static_cast<int>(1000.0/m_fps
));
969 void KMagZoomView::showSelRect(bool show
)
971 m_selRect
.alwaysVisible(show
);
974 } else if(m_mouseMode
== Normal
) {
980 * Sets the selection rectangle to the given position.
982 void KMagZoomView::setSelRectPos(const QRect
& rect
)
984 m_selRect
.setRect(rect
.x(), rect
.y(), rect
.width(), rect
.height());
989 bool KMagZoomView::showMouse(unsigned int type
)
991 if(type
> m_showMouseTypes
.count()-1)
999 unsigned int KMagZoomView::getShowMouseType() const
1001 return (m_showMouse
);
1004 QStringList
KMagZoomView::getShowMouseStringList() const
1006 return (m_showMouseTypes
);
1011 * Returns the image which is being displayed. It's again drawn by adding
1012 * the mouse cursor if needed.
1014 QPixmap
KMagZoomView::getPixmap()
1016 // show the pixel under mouse cursor
1017 if(m_showMouse
&& !m_zoomedPixmap
.isNull()) {
1018 // Pixmap which will have the zoomed pixmap + mouse
1019 QPixmap
zoomView(m_zoomedPixmap
);
1021 // paint the mouse cursor w/o updating to a newer position
1022 paintMouseCursor(&zoomView
, calcMousePos(false));
1025 } else { // no mouse cursor
1026 return(m_zoomedPixmap
);