qwt_picker.cpp
Go to the documentation of this file.
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
2  * Qwt Widget Library
3  * Copyright (C) 1997 Josef Wilgen
4  * Copyright (C) 2002 Uwe Rathmann
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the Qwt License, Version 1.0
8  *****************************************************************************/
9 
10 #include "qwt_picker.h"
11 #include "qwt_picker_machine.h"
12 #include "qwt_painter.h"
13 #include "qwt_math.h"
14 #include "qwt_widget_overlay.h"
15 #include <qapplication.h>
16 #include <qevent.h>
17 #include <qpainter.h>
18 #include <qframe.h>
19 #include <qcursor.h>
20 #include <qbitmap.h>
21 #include <qpointer.h>
22 #include <qpaintengine.h>
23 #include <qmath.h>
24 
25 static inline QRegion qwtMaskRegion( const QRect &r, int penWidth )
26 {
27  const int pw = qMax( penWidth, 1 );
28  const int pw2 = penWidth / 2;
29 
30  int x1 = r.left() - pw2;
31  int x2 = r.right() + 1 + pw2 + ( pw % 2 );
32 
33  int y1 = r.top() - pw2;
34  int y2 = r.bottom() + 1 + pw2 + ( pw % 2 );
35 
36  QRegion region;
37 
38  region += QRect( x1, y1, x2 - x1, pw );
39  region += QRect( x1, y1, pw, y2 - y1 );
40  region += QRect( x1, y2 - pw, x2 - x1, pw );
41  region += QRect( x2 - pw, y1, pw, y2 - y1 );
42 
43  return region;
44 }
45 
46 static inline QRegion qwtMaskRegion( const QLine &l, int penWidth )
47 {
48  const int pw = qMax( penWidth, 1 );
49  const int pw2 = penWidth / 2;
50 
51  QRegion region;
52 
53  if ( l.x1() == l.x2() )
54  {
55  region += QRect( l.x1() - pw2, l.y1(),
56  pw, l.y2() ).normalized();
57  }
58  else if ( l.y1() == l.y2() )
59  {
60  region += QRect( l.x1(), l.y1() - pw2,
61  l.x2(), pw ).normalized();
62  }
63 
64  return region;
65 }
66 
68 {
69 public:
70  QwtPickerRubberband( QwtPicker *, QWidget * );
71 
72 protected:
73  virtual void drawOverlay( QPainter * ) const;
74  virtual QRegion maskHint() const;
75 
77 };
78 
80 {
81 public:
82  QwtPickerTracker( QwtPicker *, QWidget * );
83 
84 protected:
85  virtual void drawOverlay( QPainter * ) const;
86  virtual QRegion maskHint() const;
87 
89 };
90 
91 
93 {
94 public:
96  enabled( false ),
97  stateMachine( NULL ),
98  resizeMode( QwtPicker::Stretch ),
99  rubberBand( QwtPicker::NoRubberBand ),
100  trackerMode( QwtPicker::AlwaysOff ),
101  isActive( false ),
102  trackerPosition( -1, -1 ),
103  mouseTracking( false ),
104  openGL( false )
105  {
106  }
107 
108  bool enabled;
109 
111 
113 
116 
119  QFont trackerFont;
120 
121  QPolygon pickedPoints;
122  bool isActive;
124 
125  bool mouseTracking; // used to save previous value
126 
127  QPointer< QwtPickerRubberband > rubberBandOverlay;
128  QPointer< QwtPickerTracker> trackerOverlay;
129 
130  bool openGL;
131 };
132 
134  QwtPicker *picker, QWidget *parent ):
135  QwtWidgetOverlay( parent ),
136  d_picker( picker )
137 {
139 }
140 
142 {
143  return d_picker->rubberBandMask();
144 }
145 
146 void QwtPickerRubberband::drawOverlay( QPainter *painter ) const
147 {
148  painter->setPen( d_picker->rubberBandPen() );
149  d_picker->drawRubberBand( painter );
150 }
151 
153  QwtPicker *picker, QWidget *parent ):
154  QwtWidgetOverlay( parent ),
155  d_picker( picker )
156 {
158 }
159 
161 {
162  return d_picker->trackerMask();
163 }
164 
165 void QwtPickerTracker::drawOverlay( QPainter *painter ) const
166 {
167  painter->setPen( d_picker->trackerPen() );
168  d_picker->drawTracker( painter );
169 }
170 
180 QwtPicker::QwtPicker( QWidget *parent ):
181  QObject( parent )
182 {
183  init( parent, NoRubberBand, AlwaysOff );
184 }
185 
194  DisplayMode trackerMode, QWidget *parent ):
195  QObject( parent )
196 {
197  init( parent, rubberBand, trackerMode );
198 }
199 
202 {
203  setMouseTracking( false );
204 
205  delete d_data->stateMachine;
206  delete d_data->rubberBandOverlay;
207  delete d_data->trackerOverlay;
208 
209  delete d_data;
210 }
211 
213 void QwtPicker::init( QWidget *parent,
215 {
216  d_data = new PrivateData;
217 
219 
220  if ( parent )
221  {
222  if ( parent->focusPolicy() == Qt::NoFocus )
223  parent->setFocusPolicy( Qt::WheelFocus );
224 
225  d_data->openGL = parent->inherits( "QGLWidget" );
226  d_data->trackerFont = parent->font();
227  d_data->mouseTracking = parent->hasMouseTracking();
228 
229  setEnabled( true );
230  }
231 
232  setTrackerMode( trackerMode );
233 }
234 
242 {
243  if ( d_data->stateMachine != stateMachine )
244  {
245  reset();
246 
247  delete d_data->stateMachine;
249 
250  if ( d_data->stateMachine )
252  }
253 }
254 
260 {
261  return d_data->stateMachine;
262 }
263 
269 {
270  return d_data->stateMachine;
271 }
272 
275 {
276  QObject *obj = parent();
277  if ( obj && obj->isWidgetType() )
278  return static_cast<QWidget *>( obj );
279 
280  return NULL;
281 }
282 
284 const QWidget *QwtPicker::parentWidget() const
285 {
286  QObject *obj = parent();
287  if ( obj && obj->isWidgetType() )
288  return static_cast< const QWidget *>( obj );
289 
290  return NULL;
291 }
292 
302 {
304 }
305 
311 {
312  return d_data->rubberBand;
313 }
314 
332 {
333  if ( d_data->trackerMode != mode )
334  {
335  d_data->trackerMode = mode;
337  }
338 }
339 
345 {
346  return d_data->trackerMode;
347 }
348 
364 {
365  d_data->resizeMode = mode;
366 }
367 
374 {
375  return d_data->resizeMode;
376 }
377 
387 void QwtPicker::setEnabled( bool enabled )
388 {
389  if ( d_data->enabled != enabled )
390  {
391  d_data->enabled = enabled;
392 
393  QWidget *w = parentWidget();
394  if ( w )
395  {
396  if ( enabled )
397  w->installEventFilter( this );
398  else
399  w->removeEventFilter( this );
400  }
401 
402  updateDisplay();
403  }
404 }
405 
411 bool QwtPicker::isEnabled() const
412 {
413  return d_data->enabled;
414 }
415 
422 void QwtPicker::setTrackerFont( const QFont &font )
423 {
424  if ( font != d_data->trackerFont )
425  {
426  d_data->trackerFont = font;
427  updateDisplay();
428  }
429 }
430 
436 QFont QwtPicker::trackerFont() const
437 {
438  return d_data->trackerFont;
439 }
440 
447 void QwtPicker::setTrackerPen( const QPen &pen )
448 {
449  if ( pen != d_data->trackerPen )
450  {
451  d_data->trackerPen = pen;
452  updateDisplay();
453  }
454 }
455 
460 QPen QwtPicker::trackerPen() const
461 {
462  return d_data->trackerPen;
463 }
464 
471 void QwtPicker::setRubberBandPen( const QPen &pen )
472 {
473  if ( pen != d_data->rubberBandPen )
474  {
475  d_data->rubberBandPen = pen;
476  updateDisplay();
477  }
478 }
479 
484 QPen QwtPicker::rubberBandPen() const
485 {
486  return d_data->rubberBandPen;
487 }
488 
502 QwtText QwtPicker::trackerText( const QPoint &pos ) const
503 {
504  QString label;
505 
506  switch ( rubberBand() )
507  {
508  case HLineRubberBand:
509  label.sprintf( "%d", pos.y() );
510  break;
511  case VLineRubberBand:
512  label.sprintf( "%d", pos.x() );
513  break;
514  default:
515  label.sprintf( "%d, %d", pos.x(), pos.y() );
516  }
517  return label;
518 }
519 
526 QRegion QwtPicker::trackerMask() const
527 {
528  return trackerRect( d_data->trackerFont );
529 }
530 
538 {
539  QRegion mask;
540 
541  if ( !isActive() || rubberBand() == NoRubberBand ||
542  rubberBandPen().style() == Qt::NoPen )
543  {
544  return mask;
545  }
546 
547  const QPolygon pa = adjustedPoints( d_data->pickedPoints );
548 
549  QwtPickerMachine::SelectionType selectionType =
551 
552  if ( d_data->stateMachine )
553  selectionType = d_data->stateMachine->selectionType();
554 
555  switch ( selectionType )
556  {
559  {
560  if ( pa.count() < 1 )
561  return mask;
562 
563  const QPoint pos = pa[0];
564  const int pw = rubberBandPen().width();
565 
566  const QRect pRect = pickArea().boundingRect().toRect();
567  switch ( rubberBand() )
568  {
569  case VLineRubberBand:
570  {
571  mask += qwtMaskRegion( QLine( pos.x(), pRect.top(),
572  pos.x(), pRect.bottom() ), pw );
573  break;
574  }
575  case HLineRubberBand:
576  {
577  mask += qwtMaskRegion( QLine( pRect.left(), pos.y(),
578  pRect.right(), pos.y() ), pw );
579  break;
580  }
581  case CrossRubberBand:
582  {
583  mask += qwtMaskRegion( QLine( pos.x(), pRect.top(),
584  pos.x(), pRect.bottom() ), pw );
585  mask += qwtMaskRegion( QLine( pRect.left(), pos.y(),
586  pRect.right(), pos.y() ), pw );
587  break;
588  }
589  default:
590  break;
591  }
592  break;
593  }
595  {
596  if ( pa.count() < 2 )
597  return mask;
598 
599  const int pw = rubberBandPen().width();
600 
601  switch ( rubberBand() )
602  {
603  case RectRubberBand:
604  {
605  const QRect r = QRect( pa.first(), pa.last() );
606  mask = qwtMaskRegion( r.normalized(), pw );
607  break;
608  }
609  case EllipseRubberBand:
610  {
611  const QRect r = QRect( pa.first(), pa.last() );
612  mask += r.adjusted( -pw, -pw, pw, pw );
613  break;
614  }
615  default:
616  break;
617  }
618  break;
619  }
621  {
622  const int pw = rubberBandPen().width();
623  if ( pw <= 1 )
624  {
625  // because of the join style we better
626  // return a mask for a pen width <= 1 only
627 
628  const int off = 2 * pw;
629  const QRect r = pa.boundingRect();
630  mask += r.adjusted( -off, -off, off, off );
631  }
632  break;
633  }
634  default:
635  break;
636  }
637 
638  return mask;
639 }
640 
649 void QwtPicker::drawRubberBand( QPainter *painter ) const
650 {
651  if ( !isActive() || rubberBand() == NoRubberBand ||
652  rubberBandPen().style() == Qt::NoPen )
653  {
654  return;
655  }
656 
657  const QPolygon pa = adjustedPoints( d_data->pickedPoints );
658 
659  QwtPickerMachine::SelectionType selectionType =
661 
662  if ( d_data->stateMachine )
663  selectionType = d_data->stateMachine->selectionType();
664 
665  switch ( selectionType )
666  {
669  {
670  if ( pa.count() < 1 )
671  return;
672 
673  const QPoint pos = pa[0];
674 
675  const QRect pRect = pickArea().boundingRect().toRect();
676  switch ( rubberBand() )
677  {
678  case VLineRubberBand:
679  {
680  QwtPainter::drawLine( painter, pos.x(),
681  pRect.top(), pos.x(), pRect.bottom() );
682  break;
683  }
684  case HLineRubberBand:
685  {
686  QwtPainter::drawLine( painter, pRect.left(),
687  pos.y(), pRect.right(), pos.y() );
688  break;
689  }
690  case CrossRubberBand:
691  {
692  QwtPainter::drawLine( painter, pos.x(),
693  pRect.top(), pos.x(), pRect.bottom() );
694  QwtPainter::drawLine( painter, pRect.left(),
695  pos.y(), pRect.right(), pos.y() );
696  break;
697  }
698  default:
699  break;
700  }
701  break;
702  }
704  {
705  if ( pa.count() < 2 )
706  return;
707 
708  const QRect rect = QRect( pa.first(), pa.last() ).normalized();
709  switch ( rubberBand() )
710  {
711  case EllipseRubberBand:
712  {
713  QwtPainter::drawEllipse( painter, rect );
714  break;
715  }
716  case RectRubberBand:
717  {
718  QwtPainter::drawRect( painter, rect );
719  break;
720  }
721  default:
722  break;
723  }
724  break;
725  }
727  {
728  if ( rubberBand() == PolygonRubberBand )
729  painter->drawPolyline( pa );
730  break;
731  }
732  default:
733  break;
734  }
735 }
736 
744 void QwtPicker::drawTracker( QPainter *painter ) const
745 {
746  const QRect textRect = trackerRect( painter->font() );
747  if ( !textRect.isEmpty() )
748  {
749  const QwtText label = trackerText( d_data->trackerPosition );
750  if ( !label.isEmpty() )
751  label.draw( painter, textRect );
752  }
753 }
754 
792 QPolygon QwtPicker::adjustedPoints( const QPolygon &points ) const
793 {
794  return points;
795 }
796 
801 QPolygon QwtPicker::selection() const
802 {
804 }
805 
808 {
809  return d_data->trackerPosition;
810 }
811 
821 QRect QwtPicker::trackerRect( const QFont &font ) const
822 {
823  if ( trackerMode() == AlwaysOff ||
824  ( trackerMode() == ActiveOnly && !isActive() ) )
825  {
826  return QRect();
827  }
828 
829  if ( d_data->trackerPosition.x() < 0 || d_data->trackerPosition.y() < 0 )
830  return QRect();
831 
833  if ( text.isEmpty() )
834  return QRect();
835 
836  const QSizeF textSize = text.textSize( font );
837  QRect textRect( 0, 0, qCeil( textSize.width() ), qCeil( textSize.height() ) );
838 
839  const QPoint &pos = d_data->trackerPosition;
840 
841  int alignment = 0;
842  if ( isActive() && d_data->pickedPoints.count() > 1
843  && rubberBand() != NoRubberBand )
844  {
845  const QPoint last =
846  d_data->pickedPoints[int( d_data->pickedPoints.count() ) - 2];
847 
848  alignment |= ( pos.x() >= last.x() ) ? Qt::AlignRight : Qt::AlignLeft;
849  alignment |= ( pos.y() > last.y() ) ? Qt::AlignBottom : Qt::AlignTop;
850  }
851  else
852  alignment = Qt::AlignTop | Qt::AlignRight;
853 
854  const int margin = 5;
855 
856  int x = pos.x();
857  if ( alignment & Qt::AlignLeft )
858  x -= textRect.width() + margin;
859  else if ( alignment & Qt::AlignRight )
860  x += margin;
861 
862  int y = pos.y();
863  if ( alignment & Qt::AlignBottom )
864  y += margin;
865  else if ( alignment & Qt::AlignTop )
866  y -= textRect.height() + margin;
867 
868  textRect.moveTopLeft( QPoint( x, y ) );
869 
870  const QRect pickRect = pickArea().boundingRect().toRect();
871 
872  int right = qMin( textRect.right(), pickRect.right() - margin );
873  int bottom = qMin( textRect.bottom(), pickRect.bottom() - margin );
874  textRect.moveBottomRight( QPoint( right, bottom ) );
875 
876  int left = qMax( textRect.left(), pickRect.left() + margin );
877  int top = qMax( textRect.top(), pickRect.top() + margin );
878  textRect.moveTopLeft( QPoint( left, top ) );
879 
880  return textRect;
881 }
882 
902 bool QwtPicker::eventFilter( QObject *object, QEvent *event )
903 {
904  if ( object && object == parentWidget() )
905  {
906  switch ( event->type() )
907  {
908  case QEvent::Resize:
909  {
910  const QResizeEvent *re = static_cast<QResizeEvent *>( event );
911 
912  /*
913  Adding/deleting additional event filters inside of an event filter
914  is not safe dues to the implementation in Qt ( changing alist while iterating ).
915  So we create the overlays in a way, that they don't install en event filter
916  ( parent set to NULL ) and do the resizing here.
917  */
918  if ( d_data->trackerOverlay )
919  d_data->trackerOverlay->resize( re->size() );
920 
921  if ( d_data->rubberBandOverlay )
922  d_data->rubberBandOverlay->resize( re->size() );
923 
924  if ( d_data->resizeMode == Stretch )
925  stretchSelection( re->oldSize(), re->size() );
926 
927  updateDisplay();
928  break;
929  }
930  case QEvent::Enter:
931  {
932  widgetEnterEvent( event );
933  break;
934  }
935  case QEvent::Leave:
936  {
937  widgetLeaveEvent( event );
938  break;
939  }
940  case QEvent::MouseButtonPress:
941  {
942  widgetMousePressEvent( static_cast<QMouseEvent *>( event ) );
943  break;
944  }
945  case QEvent::MouseButtonRelease:
946  {
947  widgetMouseReleaseEvent( static_cast<QMouseEvent *>( event ) );
948  break;
949  }
950  case QEvent::MouseButtonDblClick:
951  {
952  widgetMouseDoubleClickEvent( static_cast<QMouseEvent *>( event ) );
953  break;
954  }
955  case QEvent::MouseMove:
956  {
957  widgetMouseMoveEvent( static_cast<QMouseEvent *>( event ) );
958  break;
959  }
960  case QEvent::KeyPress:
961  {
962  widgetKeyPressEvent( static_cast<QKeyEvent *>( event ) );
963  break;
964  }
965  case QEvent::KeyRelease:
966  {
967  widgetKeyReleaseEvent( static_cast<QKeyEvent *>( event ) );
968  break;
969  }
970  case QEvent::Wheel:
971  {
972  widgetWheelEvent( static_cast<QWheelEvent *>( event ) );
973  break;
974  }
975  default:
976  break;
977  }
978  }
979  return false;
980 }
981 
991 void QwtPicker::widgetMousePressEvent( QMouseEvent *mouseEvent )
992 {
993  transition( mouseEvent );
994 }
995 
1005 void QwtPicker::widgetMouseMoveEvent( QMouseEvent *mouseEvent )
1006 {
1007  if ( pickArea().contains( mouseEvent->pos() ) )
1008  d_data->trackerPosition = mouseEvent->pos();
1009  else
1010  d_data->trackerPosition = QPoint( -1, -1 );
1011 
1012  if ( !isActive() )
1013  updateDisplay();
1014 
1015  transition( mouseEvent );
1016 }
1017 
1027 void QwtPicker::widgetEnterEvent( QEvent *event )
1028 {
1029  transition( event );
1030 }
1031 
1041 void QwtPicker::widgetLeaveEvent( QEvent *event )
1042 {
1043  transition( event );
1044 
1045  d_data->trackerPosition = QPoint( -1, -1 );
1046  if ( !isActive() )
1047  updateDisplay();
1048 }
1049 
1059 void QwtPicker::widgetMouseReleaseEvent( QMouseEvent *mouseEvent )
1060 {
1061  transition( mouseEvent );
1062 }
1063 
1073 void QwtPicker::widgetMouseDoubleClickEvent( QMouseEvent *mouseEvent )
1074 {
1075  transition( mouseEvent );
1076 }
1077 
1078 
1090 void QwtPicker::widgetWheelEvent( QWheelEvent *wheelEvent )
1091 {
1092  if ( pickArea().contains( wheelEvent->pos() ) )
1093  d_data->trackerPosition = wheelEvent->pos();
1094  else
1095  d_data->trackerPosition = QPoint( -1, -1 );
1096 
1097  updateDisplay();
1098 
1099  transition( wheelEvent );
1100 }
1101 
1116 void QwtPicker::widgetKeyPressEvent( QKeyEvent *keyEvent )
1117 {
1118  int dx = 0;
1119  int dy = 0;
1120 
1121  int offset = 1;
1122  if ( keyEvent->isAutoRepeat() )
1123  offset = 5;
1124 
1125  if ( keyMatch( KeyLeft, keyEvent ) )
1126  dx = -offset;
1127  else if ( keyMatch( KeyRight, keyEvent ) )
1128  dx = offset;
1129  else if ( keyMatch( KeyUp, keyEvent ) )
1130  dy = -offset;
1131  else if ( keyMatch( KeyDown, keyEvent ) )
1132  dy = offset;
1133  else if ( keyMatch( KeyAbort, keyEvent ) )
1134  {
1135  reset();
1136  }
1137  else
1138  transition( keyEvent );
1139 
1140  if ( dx != 0 || dy != 0 )
1141  {
1142  const QRect rect = pickArea().boundingRect().toRect();
1143  const QPoint pos = parentWidget()->mapFromGlobal( QCursor::pos() );
1144 
1145  int x = pos.x() + dx;
1146  x = qMax( rect.left(), x );
1147  x = qMin( rect.right(), x );
1148 
1149  int y = pos.y() + dy;
1150  y = qMax( rect.top(), y );
1151  y = qMin( rect.bottom(), y );
1152 
1153  QCursor::setPos( parentWidget()->mapToGlobal( QPoint( x, y ) ) );
1154  }
1155 }
1156 
1168 void QwtPicker::widgetKeyReleaseEvent( QKeyEvent *keyEvent )
1169 {
1170  transition( keyEvent );
1171 }
1172 
1180 void QwtPicker::transition( const QEvent *event )
1181 {
1182  if ( !d_data->stateMachine )
1183  return;
1184 
1185  const QList<QwtPickerMachine::Command> commandList =
1186  d_data->stateMachine->transition( *this, event );
1187 
1188  QPoint pos;
1189  switch ( event->type() )
1190  {
1191  case QEvent::MouseButtonDblClick:
1192  case QEvent::MouseButtonPress:
1193  case QEvent::MouseButtonRelease:
1194  case QEvent::MouseMove:
1195  {
1196  const QMouseEvent *me =
1197  static_cast< const QMouseEvent * >( event );
1198  pos = me->pos();
1199  break;
1200  }
1201  default:
1202  pos = parentWidget()->mapFromGlobal( QCursor::pos() );
1203  }
1204 
1205  for ( int i = 0; i < commandList.count(); i++ )
1206  {
1207  switch ( commandList[i] )
1208  {
1210  {
1211  begin();
1212  break;
1213  }
1215  {
1216  append( pos );
1217  break;
1218  }
1220  {
1221  move( pos );
1222  break;
1223  }
1225  {
1226  remove();
1227  break;
1228  }
1229  case QwtPickerMachine::End:
1230  {
1231  end();
1232  break;
1233  }
1234  }
1235  }
1236 }
1237 
1244 {
1245  if ( d_data->isActive )
1246  return;
1247 
1248  d_data->pickedPoints.resize( 0 );
1249  d_data->isActive = true;
1250  Q_EMIT activated( true );
1251 
1252  if ( trackerMode() != AlwaysOff )
1253  {
1254  if ( d_data->trackerPosition.x() < 0 || d_data->trackerPosition.y() < 0 )
1255  {
1256  QWidget *w = parentWidget();
1257  if ( w )
1258  d_data->trackerPosition = w->mapFromGlobal( QCursor::pos() );
1259  }
1260  }
1261 
1262  updateDisplay();
1263  setMouseTracking( true );
1264 }
1265 
1276 bool QwtPicker::end( bool ok )
1277 {
1278  if ( d_data->isActive )
1279  {
1280  setMouseTracking( false );
1281 
1282  d_data->isActive = false;
1283  Q_EMIT activated( false );
1284 
1285  if ( trackerMode() == ActiveOnly )
1286  d_data->trackerPosition = QPoint( -1, -1 );
1287 
1288  if ( ok )
1289  ok = accept( d_data->pickedPoints );
1290 
1291  if ( ok )
1292  Q_EMIT selected( d_data->pickedPoints );
1293  else
1294  d_data->pickedPoints.resize( 0 );
1295 
1296  updateDisplay();
1297  }
1298  else
1299  ok = false;
1300 
1301  return ok;
1302 }
1303 
1308 {
1309  if ( d_data->stateMachine )
1311 
1312  if ( isActive() )
1313  end( false );
1314 }
1315 
1324 void QwtPicker::append( const QPoint &pos )
1325 {
1326  if ( d_data->isActive )
1327  {
1328  const int idx = d_data->pickedPoints.count();
1329  d_data->pickedPoints.resize( idx + 1 );
1330  d_data->pickedPoints[idx] = pos;
1331 
1332  updateDisplay();
1333  Q_EMIT appended( pos );
1334  }
1335 }
1336 
1344 void QwtPicker::move( const QPoint &pos )
1345 {
1346  if ( d_data->isActive )
1347  {
1348  const int idx = d_data->pickedPoints.count() - 1;
1349  if ( idx >= 0 )
1350  {
1351  if ( d_data->pickedPoints[idx] != pos )
1352  {
1353  d_data->pickedPoints[idx] = pos;
1354 
1355  updateDisplay();
1356  Q_EMIT moved( pos );
1357  }
1358  }
1359  }
1360 }
1361 
1369 {
1370  if ( d_data->isActive )
1371  {
1372  const int idx = d_data->pickedPoints.count() - 1;
1373  if ( idx > 0 )
1374  {
1375  const int idx = d_data->pickedPoints.count();
1376 
1377  const QPoint pos = d_data->pickedPoints[idx - 1];
1378  d_data->pickedPoints.resize( idx - 1 );
1379 
1380  updateDisplay();
1381  Q_EMIT removed( pos );
1382  }
1383  }
1384 }
1385 
1394 bool QwtPicker::accept( QPolygon &selection ) const
1395 {
1396  Q_UNUSED( selection );
1397  return true;
1398 }
1399 
1405 {
1406  return d_data->isActive;
1407 }
1408 
1414 const QPolygon &QwtPicker::pickedPoints() const
1415 {
1416  return d_data->pickedPoints;
1417 }
1418 
1428 void QwtPicker::stretchSelection( const QSize &oldSize, const QSize &newSize )
1429 {
1430  if ( oldSize.isEmpty() )
1431  {
1432  // avoid division by zero. But scaling for small sizes also
1433  // doesn't make much sense, because of rounding losses. TODO ...
1434  return;
1435  }
1436 
1437  const double xRatio =
1438  double( newSize.width() ) / double( oldSize.width() );
1439  const double yRatio =
1440  double( newSize.height() ) / double( oldSize.height() );
1441 
1442  for ( int i = 0; i < int( d_data->pickedPoints.count() ); i++ )
1443  {
1444  QPoint &p = d_data->pickedPoints[i];
1445  p.setX( qRound( p.x() * xRatio ) );
1446  p.setY( qRound( p.y() * yRatio ) );
1447 
1448  Q_EMIT changed( d_data->pickedPoints );
1449  }
1450 }
1451 
1465 void QwtPicker::setMouseTracking( bool enable )
1466 {
1467  QWidget *widget = parentWidget();
1468  if ( !widget )
1469  return;
1470 
1471  if ( enable )
1472  {
1473  d_data->mouseTracking = widget->hasMouseTracking();
1474  widget->setMouseTracking( true );
1475  }
1476  else
1477  {
1478  widget->setMouseTracking( d_data->mouseTracking );
1479  }
1480 }
1481 
1487 QPainterPath QwtPicker::pickArea() const
1488 {
1489  QPainterPath path;
1490 
1491  const QWidget *widget = parentWidget();
1492  if ( widget )
1493  path.addRect( widget->contentsRect() );
1494 
1495  return path;
1496 }
1497 
1500 {
1501  QWidget *w = parentWidget();
1502 
1503  bool showRubberband = false;
1504  bool showTracker = false;
1505 
1506  if ( w && w->isVisible() && d_data->enabled )
1507  {
1508  if ( rubberBand() != NoRubberBand && isActive() &&
1509  rubberBandPen().style() != Qt::NoPen )
1510  {
1511  showRubberband = true;
1512  }
1513 
1514  if ( trackerMode() == AlwaysOn ||
1515  ( trackerMode() == ActiveOnly && isActive() ) )
1516  {
1517  if ( trackerPen() != Qt::NoPen
1518  && !trackerRect( QFont() ).isEmpty() )
1519  {
1520  showTracker = true;
1521  }
1522  }
1523  }
1524 
1525  QPointer< QwtPickerRubberband > &rw = d_data->rubberBandOverlay;
1526  if ( showRubberband )
1527  {
1528  if ( rw.isNull() )
1529  {
1530  rw = new QwtPickerRubberband( this, NULL ); // NULL -> no extra event filter
1531  rw->setObjectName( "PickerRubberBand" );
1532  rw->setParent( w );
1533  rw->resize( w->size() );
1534  }
1535 
1536  if ( d_data->rubberBand <= RectRubberBand )
1537  rw->setMaskMode( QwtWidgetOverlay::MaskHint );
1538  else
1539  rw->setMaskMode( QwtWidgetOverlay::AlphaMask );
1540 
1541  rw->updateOverlay();
1542  }
1543  else
1544  {
1545  if ( d_data->openGL )
1546  {
1547  // Qt 4.8 crashes for a delete
1548  if ( !rw.isNull() )
1549  {
1550  rw->hide();
1551  rw->deleteLater();
1552  rw = NULL;
1553  }
1554  }
1555  else
1556  {
1557  delete rw;
1558  }
1559  }
1560 
1561  QPointer< QwtPickerTracker > &tw = d_data->trackerOverlay;
1562  if ( showTracker )
1563  {
1564  if ( tw.isNull() )
1565  {
1566  tw = new QwtPickerTracker( this, NULL ); // NULL -> no extra event filter
1567  tw->setObjectName( "PickerTracker" );
1568  tw->setParent( w );
1569  tw->resize( w->size() );
1570  }
1571  tw->setFont( d_data->trackerFont );
1572  tw->updateOverlay();
1573  }
1574  else
1575  {
1576  if ( d_data->openGL )
1577  {
1578  // Qt 4.8 crashes for a delete
1579  if ( !tw.isNull() )
1580  {
1581  tw->hide();
1582  tw->deleteLater();
1583  tw = NULL;
1584  }
1585  }
1586  else
1587  {
1588  delete tw;
1589  }
1590  }
1591 }
1592 
1595 {
1596  return d_data->rubberBandOverlay;
1597 }
1598 
1601 {
1602  return d_data->trackerOverlay;
1603 }
1604 
virtual QRegion trackerMask() const
Definition: qwt_picker.cpp:526
virtual bool end(bool ok=true)
Close a selection setting the state to inactive.
virtual void widgetKeyPressEvent(QKeyEvent *)
virtual void remove()
DisplayMode
Display mode.
Definition: qwt_picker.h:153
QwtPicker * d_picker
Definition: qwt_picker.cpp:88
virtual void stretchSelection(const QSize &oldSize, const QSize &newSize)
void setRubberBand(RubberBand)
Definition: qwt_picker.cpp:301
static void drawLine(QPainter *, double x1, double y1, double x2, double y2)
Wrapper for QPainter::drawLine()
Definition: qwt_painter.h:147
DisplayMode trackerMode() const
const QwtWidgetOverlay * rubberBandOverlay() const
void setTrackerFont(const QFont &)
Definition: qwt_picker.cpp:422
virtual void widgetEnterEvent(QEvent *)
virtual void widgetKeyReleaseEvent(QKeyEvent *)
A crosshair ( only for QwtPickerMachine::PointSelection )
Definition: qwt_picker.h:131
static QRegion qwtMaskRegion(const QRect &r, int penWidth)
Definition: qwt_picker.cpp:25
The state machine not usable for any type of selection.
Display always.
Definition: qwt_picker.h:159
virtual QRegion rubberBandMask() const
Definition: qwt_picker.cpp:537
QWidget * parentWidget()
Return the parent widget, where the selection happens.
Definition: qwt_picker.cpp:274
void setTrackerMode(DisplayMode)
Set the display mode of the tracker.
Definition: qwt_picker.cpp:331
QPointer< QwtPickerRubberband > rubberBandOverlay
Definition: qwt_picker.cpp:127
QwtPickerTracker(QwtPicker *, QWidget *)
Definition: qwt_picker.cpp:152
void reset()
Set the current state to 0.
QPoint trackerPosition() const
Definition: qwt_picker.cpp:807
QwtPicker * d_picker
Definition: qwt_picker.cpp:76
QPointer< QwtPickerTracker > trackerOverlay
Definition: qwt_picker.cpp:128
virtual void reset()
void draw(QPainter *painter, const QRectF &rect) const
Definition: qwt_text.cpp:560
void setMaskMode(MaskMode)
Specify how to find the mask for the overlay.
QPen rubberBandPen() const
const QPolygon & pickedPoints() const
QFont trackerFont() const
QPolygon selection() const
Definition: qwt_picker.cpp:801
virtual bool eventFilter(QObject *, QEvent *)
Event filter.
Definition: qwt_picker.cpp:902
virtual bool accept(QPolygon &) const
Validate and fix up the selection.
TFSIMD_FORCE_INLINE const tfScalar & y() const
void selected(const QPolygon &polygon)
virtual void widgetLeaveEvent(QEvent *)
QPen trackerPen() const
bool isActive() const
void changed(const QPolygon &selection)
All points are scaled according to the new size,.
Definition: qwt_picker.h:176
void moved(const QPoint &pos)
The state machine is for selecting a polygon (many points).
PrivateData * d_data
Definition: qwt_picker.h:326
No rubberband.
Definition: qwt_picker.h:122
void setMouseTracking(bool)
TFSIMD_FORCE_INLINE Vector3 normalized() const
QSizeF textSize(const QFont &=QFont()) const
Definition: qwt_text.cpp:526
virtual void drawOverlay(QPainter *) const
Definition: qwt_picker.cpp:165
virtual QPainterPath pickArea() const
const QwtPickerMachine * stateMachine() const
Definition: qwt_picker.cpp:268
virtual void drawRubberBand(QPainter *) const
Definition: qwt_picker.cpp:649
QwtPicker::ResizeMode resizeMode
Definition: qwt_picker.cpp:112
The state machine is for selecting a single point.
GraphId path[kMaxDeadlockPathLen]
static void drawRect(QPainter *, double x, double y, double w, double h)
Wrapper for QPainter::drawRect()
A polygon ( only for QwtPickerMachine::PolygonSelection )
Definition: qwt_picker.h:140
void setStateMachine(QwtPickerMachine *)
Definition: qwt_picker.cpp:241
virtual QRect trackerRect(const QFont &) const
Definition: qwt_picker.cpp:821
virtual void widgetMouseMoveEvent(QMouseEvent *)
bool isEmpty() const
Definition: qwt_text.h:213
virtual void transition(const QEvent *)
An ellipse ( only for QwtPickerMachine::RectSelection )
Definition: qwt_picker.h:137
virtual void widgetMouseDoubleClickEvent(QMouseEvent *)
RubberBand rubberBand() const
QwtPicker::DisplayMode trackerMode
Definition: qwt_picker.cpp:117
A class representing a text.
Definition: qwt_text.h:51
A state machine for QwtPicker selections.
virtual void move(const QPoint &)
TFSIMD_FORCE_INLINE const tfScalar & x() const
A horizontal line ( only for QwtPickerMachine::PointSelection )
Definition: qwt_picker.h:125
virtual void widgetWheelEvent(QWheelEvent *)
QwtPicker::RubberBand rubberBand
Definition: qwt_picker.cpp:114
virtual void updateDisplay()
Update the state of rubber band and tracker label.
static void drawEllipse(QPainter *, const QRectF &)
Wrapper for QPainter::drawEllipse()
QPen rubberBandPen
Definition: qwt_picker.h:109
void setEnabled(bool)
En/disable the picker.
Definition: qwt_picker.cpp:387
Use maskHint() as mask.
void appended(const QPoint &pos)
virtual QList< Command > transition(const QwtEventPattern &, const QEvent *)=0
Transition.
TFSIMD_FORCE_INLINE const tfScalar & w() const
virtual void drawTracker(QPainter *) const
Definition: qwt_picker.cpp:744
const QwtWidgetOverlay * trackerOverlay() const
Calculate a mask by checking the alpha values.
A rectangle ( only for QwtPickerMachine::RectSelection )
Definition: qwt_picker.h:134
An overlay for a widget.
virtual QPolygon adjustedPoints(const QPolygon &) const
Map the pickedPoints() into a selection()
Definition: qwt_picker.cpp:792
bool isEnabled() const
virtual void widgetMouseReleaseEvent(QMouseEvent *)
virtual QRegion maskHint() const
Calculate an approximation for the mask.
Definition: qwt_picker.cpp:160
bool keyMatch(KeyPatternCode, const QKeyEvent *) const
Compare a key event with an event pattern.
void setResizeMode(ResizeMode)
Set the resize mode.
Definition: qwt_picker.cpp:363
SelectionType selectionType() const
Return the selection type.
A vertical line ( only for QwtPickerMachine::PointSelection )
Definition: qwt_picker.h:128
void removed(const QPoint &pos)
Display never.
Definition: qwt_picker.h:156
QwtPicker(QWidget *parent)
Definition: qwt_picker.cpp:180
virtual ~QwtPicker()
Destructor.
Definition: qwt_picker.cpp:201
int i
virtual void drawOverlay(QPainter *) const
Definition: qwt_picker.cpp:146
virtual QwtText trackerText(const QPoint &pos) const
Return the label for a position.
Definition: qwt_picker.cpp:502
void setRubberBandPen(const QPen &)
Definition: qwt_picker.cpp:471
virtual QRegion maskHint() const
Calculate an approximation for the mask.
Definition: qwt_picker.cpp:141
virtual void begin()
ResizeMode resizeMode() const
QPen trackerPen
Definition: qwt_picker.h:105
virtual void widgetMousePressEvent(QMouseEvent *)
Definition: qwt_picker.cpp:991
void init(QWidget *, RubberBand rubberBand, DisplayMode trackerMode)
Initialize the picker - used by the constructors.
Definition: qwt_picker.cpp:213
void setTrackerPen(const QPen &)
Definition: qwt_picker.cpp:447
QwtPicker provides selections on a widget.
Definition: qwt_picker.h:95
QwtPickerRubberband(QwtPicker *, QWidget *)
Definition: qwt_picker.cpp:133
The state machine is for selecting a rectangle (2 points).
void activated(bool on)
QwtPickerMachine * stateMachine
Definition: qwt_picker.cpp:110
virtual void append(const QPoint &)
Display only when the selection is active.
Definition: qwt_picker.h:162


plotjuggler
Author(s): Davide Faconti
autogenerated on Sat Jul 6 2019 03:44:17