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 | #ifndef QWT_PICKER
|
---|
11 | #define QWT_PICKER 1
|
---|
12 |
|
---|
13 | #include <qobject.h>
|
---|
14 | #include <qpen.h>
|
---|
15 | #include <qfont.h>
|
---|
16 | #include <qrect.h>
|
---|
17 | #include "qwt_global.h"
|
---|
18 | #include "qwt_text.h"
|
---|
19 | #include "qwt_polygon.h"
|
---|
20 | #include "qwt_event_pattern.h"
|
---|
21 |
|
---|
22 | class QWidget;
|
---|
23 | class QMouseEvent;
|
---|
24 | class QWheelEvent;
|
---|
25 | class QKeyEvent;
|
---|
26 | class QwtPickerMachine;
|
---|
27 |
|
---|
28 | /*!
|
---|
29 | \brief QwtPicker provides selections on a widget
|
---|
30 |
|
---|
31 | QwtPicker filters all mouse and keyboard events of a widget
|
---|
32 | and translates them into an array of selected points. Depending
|
---|
33 | on the QwtPicker::SelectionType the selection might be a single point,
|
---|
34 | a rectangle or a polygon. The selection process is supported by
|
---|
35 | optional rubberbands (rubberband selection) and position trackers.
|
---|
36 |
|
---|
37 | QwtPicker is useful for widgets where the event handlers
|
---|
38 | can't be overloaded, like for components of composite widgets.
|
---|
39 | It offers alternative handlers for mouse and key events.
|
---|
40 |
|
---|
41 | \par Example
|
---|
42 | \verbatim #include <qwt_picker.h>
|
---|
43 |
|
---|
44 | QwtPicker *picker = new QwtPicker(widget);
|
---|
45 | picker->setTrackerMode(QwtPicker::ActiveOnly);
|
---|
46 | connect(picker, SIGNAL(selected(const QwtPolygon &)), ...);
|
---|
47 |
|
---|
48 | // emit the position of clicks on widget
|
---|
49 | picker->setSelectionFlags(QwtPicker::PointSelection | QwtPicker::ClickSelection);
|
---|
50 |
|
---|
51 | ...
|
---|
52 |
|
---|
53 | // now select rectangles
|
---|
54 | picker->setSelectionFlags(QwtPicker::RectSelection | QwtPicker::DragSelection);
|
---|
55 | picker->setRubberBand(QwtPicker::RectRubberBand); \endverbatim\n
|
---|
56 |
|
---|
57 | The selection process uses the commands begin(), append(), move() and end().
|
---|
58 | append() adds a new point to the selection, move() changes the position of
|
---|
59 | the latest point.
|
---|
60 |
|
---|
61 | The commands are initiated from a small state machine (QwtPickerMachine)
|
---|
62 | that translates mouse and key events. There are a couple of predefined
|
---|
63 | state machines for point, rect and polygon selections. The selectionFlags()
|
---|
64 | control which one should be used. It is possible to use other machines
|
---|
65 | by overloading stateMachine().
|
---|
66 |
|
---|
67 | The picker is active (isActive()), between begin() and end().
|
---|
68 | In active state the rubberband is displayed, and the tracker is visible
|
---|
69 | in case of trackerMode is ActiveOnly or AlwaysOn.
|
---|
70 |
|
---|
71 | The cursor can be moved using the arrow keys. All selections can be aborted
|
---|
72 | using the abort key. (QwtEventPattern::KeyPatternCode)
|
---|
73 |
|
---|
74 | \warning In case of QWidget::NoFocus the focus policy of the observed
|
---|
75 | widget is set to QWidget::WheelFocus and mouse tracking
|
---|
76 | will be manipulated for ClickSelection while the picker is active,
|
---|
77 | or if trackerMode() is AlwayOn.
|
---|
78 | */
|
---|
79 |
|
---|
80 | class QWT_EXPORT QwtPicker: public QObject, public QwtEventPattern
|
---|
81 | {
|
---|
82 | Q_OBJECT
|
---|
83 |
|
---|
84 | Q_ENUMS(RubberBand)
|
---|
85 | Q_ENUMS(DisplayMode)
|
---|
86 | Q_ENUMS(ResizeMode)
|
---|
87 |
|
---|
88 | Q_PROPERTY(int selectionFlags READ selectionFlags WRITE setSelectionFlags)
|
---|
89 | Q_PROPERTY(DisplayMode trackerMode READ trackerMode WRITE setTrackerMode)
|
---|
90 | Q_PROPERTY(QFont trackerFont READ trackerFont WRITE setTrackerFont)
|
---|
91 | Q_PROPERTY(RubberBand rubberBand READ rubberBand WRITE setRubberBand)
|
---|
92 | Q_PROPERTY(ResizeMode resizeMode READ resizeMode WRITE setResizeMode)
|
---|
93 | Q_PROPERTY(bool isEnabled READ isEnabled WRITE setEnabled)
|
---|
94 |
|
---|
95 | Q_PROPERTY(QPen trackerPen READ trackerPen WRITE setTrackerPen)
|
---|
96 | Q_PROPERTY(QPen rubberBandPen READ rubberBandPen WRITE setRubberBandPen)
|
---|
97 |
|
---|
98 | public:
|
---|
99 | /*!
|
---|
100 | This enum type describes the type of a selection. It can be or'd
|
---|
101 | with QwtPicker::RectSelectionType and QwtPicker::SelectionMode
|
---|
102 | and passed to QwtPicker::setSelectionFlags()
|
---|
103 | - NoSelection\n
|
---|
104 | Selection is disabled. Note this is different to the disabled
|
---|
105 | state, as you might have a tracker.
|
---|
106 | - PointSelection\n
|
---|
107 | Select a single point.
|
---|
108 | - RectSelection\n
|
---|
109 | Select a rectangle.
|
---|
110 | - PolygonSelection\n
|
---|
111 | Select a polygon.
|
---|
112 |
|
---|
113 | The default value is NoSelection.
|
---|
114 | \sa QwtPicker::setSelectionFlags(), QwtPicker::selectionFlags()
|
---|
115 | */
|
---|
116 |
|
---|
117 | enum SelectionType
|
---|
118 | {
|
---|
119 | NoSelection = 0,
|
---|
120 | PointSelection = 1,
|
---|
121 | RectSelection = 2,
|
---|
122 | PolygonSelection = 4
|
---|
123 | };
|
---|
124 |
|
---|
125 | /*!
|
---|
126 | \brief Selection subtype for RectSelection
|
---|
127 | This enum type describes the type of rectangle selections.
|
---|
128 | It can be or'd with QwtPicker::RectSelectionType and
|
---|
129 | QwtPicker::SelectionMode and passed to QwtPicker::setSelectionFlags().
|
---|
130 | - CornerToCorner\n
|
---|
131 | The first and the second selected point are the corners
|
---|
132 | of the rectangle.
|
---|
133 | - CenterToCorner\n
|
---|
134 | The first point is the center, the second a corner of the
|
---|
135 | rectangle.
|
---|
136 | - CenterToRadius\n
|
---|
137 | The first point is the center of a quadrat, calculated by the maximum
|
---|
138 | of the x- and y-distance.
|
---|
139 |
|
---|
140 | The default value is CornerToCorner.
|
---|
141 | \sa QwtPicker::setSelectionFlags(), QwtPicker::selectionFlags()
|
---|
142 | */
|
---|
143 | enum RectSelectionType
|
---|
144 | {
|
---|
145 | CornerToCorner = 64,
|
---|
146 | CenterToCorner = 128,
|
---|
147 | CenterToRadius = 256
|
---|
148 | };
|
---|
149 |
|
---|
150 | /*!
|
---|
151 | Values of this enum type or'd together with a SelectionType value
|
---|
152 | identifies which state machine should be used for the selection.
|
---|
153 |
|
---|
154 | The default value is ClickSelection.
|
---|
155 | \sa stateMachine()
|
---|
156 | */
|
---|
157 | enum SelectionMode
|
---|
158 | {
|
---|
159 | ClickSelection = 1024,
|
---|
160 | DragSelection = 2048
|
---|
161 | };
|
---|
162 |
|
---|
163 | /*!
|
---|
164 | Rubberband style
|
---|
165 | - NoRubberBand\n
|
---|
166 | No rubberband.
|
---|
167 | - HLineRubberBand & PointSelection\n
|
---|
168 | A horizontal line.
|
---|
169 | - VLineRubberBand & PointSelection\n
|
---|
170 | A vertical line.
|
---|
171 | - CrossRubberBand & PointSelection\n
|
---|
172 | A horizontal and a vertical line.
|
---|
173 | - RectRubberBand & RectSelection\n
|
---|
174 | A rectangle.
|
---|
175 | - EllipseRubberBand & RectSelection\n
|
---|
176 | An ellipse.
|
---|
177 | - PolygonRubberBand &PolygonSelection\n
|
---|
178 | A polygon.
|
---|
179 | - UserRubberBand\n
|
---|
180 | Values >= UserRubberBand can be used to define additional
|
---|
181 | rubber bands.
|
---|
182 |
|
---|
183 | The default value is NoRubberBand.
|
---|
184 | \sa QwtPicker::setRubberBand(), QwtPicker::rubberBand()
|
---|
185 | */
|
---|
186 |
|
---|
187 | enum RubberBand
|
---|
188 | {
|
---|
189 | NoRubberBand = 0,
|
---|
190 |
|
---|
191 | // Point
|
---|
192 | HLineRubberBand,
|
---|
193 | VLineRubberBand,
|
---|
194 | CrossRubberBand,
|
---|
195 |
|
---|
196 | // Rect
|
---|
197 | RectRubberBand,
|
---|
198 | EllipseRubberBand,
|
---|
199 |
|
---|
200 | // Polygon
|
---|
201 | PolygonRubberBand,
|
---|
202 |
|
---|
203 | UserRubberBand = 100
|
---|
204 | };
|
---|
205 |
|
---|
206 | /*!
|
---|
207 | - AlwaysOff\n
|
---|
208 | Display never.
|
---|
209 | - AlwaysOn\n
|
---|
210 | Display always.
|
---|
211 | - ActiveOnly\n
|
---|
212 | Display only when the selection is active.
|
---|
213 |
|
---|
214 | \sa QwtPicker::setTrackerMode(), QwtPicker::trackerMode(),
|
---|
215 | QwtPicker::isActive()
|
---|
216 | */
|
---|
217 | enum DisplayMode
|
---|
218 | {
|
---|
219 | AlwaysOff,
|
---|
220 | AlwaysOn,
|
---|
221 | ActiveOnly
|
---|
222 | };
|
---|
223 |
|
---|
224 | /*!
|
---|
225 | Controls what to do with the selected points of an active
|
---|
226 | selection when the observed widget is resized.
|
---|
227 | - Stretch\n
|
---|
228 | All points are scaled according to the new size,
|
---|
229 | - KeepSize\n
|
---|
230 | All points remain unchanged.
|
---|
231 |
|
---|
232 | The default value is Stretch.
|
---|
233 | \sa QwtPicker::setResizeMode(), QwtPicker::resize()
|
---|
234 | */
|
---|
235 |
|
---|
236 | enum ResizeMode
|
---|
237 | {
|
---|
238 | Stretch,
|
---|
239 | KeepSize
|
---|
240 | };
|
---|
241 |
|
---|
242 | explicit QwtPicker(QWidget *parent);
|
---|
243 | explicit QwtPicker(int selectionFlags, RubberBand rubberBand,
|
---|
244 | DisplayMode trackerMode, QWidget *);
|
---|
245 |
|
---|
246 | virtual ~QwtPicker();
|
---|
247 |
|
---|
248 | virtual void setSelectionFlags(int);
|
---|
249 | int selectionFlags() const;
|
---|
250 |
|
---|
251 | virtual void setRubberBand(RubberBand);
|
---|
252 | RubberBand rubberBand() const;
|
---|
253 |
|
---|
254 | virtual void setTrackerMode(DisplayMode);
|
---|
255 | DisplayMode trackerMode() const;
|
---|
256 |
|
---|
257 | virtual void setResizeMode(ResizeMode);
|
---|
258 | ResizeMode resizeMode() const;
|
---|
259 |
|
---|
260 | virtual void setRubberBandPen(const QPen &);
|
---|
261 | QPen rubberBandPen() const;
|
---|
262 |
|
---|
263 | virtual void setTrackerPen(const QPen &);
|
---|
264 | QPen trackerPen() const;
|
---|
265 |
|
---|
266 | virtual void setTrackerFont(const QFont &);
|
---|
267 | QFont trackerFont() const;
|
---|
268 |
|
---|
269 | bool isEnabled() const;
|
---|
270 | virtual void setEnabled(bool);
|
---|
271 |
|
---|
272 | bool isActive() const;
|
---|
273 |
|
---|
274 | virtual bool eventFilter(QObject *, QEvent *);
|
---|
275 |
|
---|
276 | QWidget *parentWidget();
|
---|
277 | const QWidget *parentWidget() const;
|
---|
278 |
|
---|
279 | virtual QRect pickRect() const;
|
---|
280 | const QwtPolygon &selection() const;
|
---|
281 |
|
---|
282 | virtual void drawRubberBand(QPainter *) const;
|
---|
283 | virtual void drawTracker(QPainter *) const;
|
---|
284 |
|
---|
285 | virtual QwtText trackerText(const QPoint &pos) const;
|
---|
286 | QPoint trackerPosition() const;
|
---|
287 | QRect trackerRect(const QFont &) const;
|
---|
288 |
|
---|
289 |
|
---|
290 | signals:
|
---|
291 | /*!
|
---|
292 | A signal emitting the selected points,
|
---|
293 | at the end of a selection.
|
---|
294 |
|
---|
295 | \param pa Selected points
|
---|
296 | */
|
---|
297 | void selected(const QwtPolygon &pa);
|
---|
298 |
|
---|
299 | /*!
|
---|
300 | A signal emitted when a point has been appended to the selection
|
---|
301 |
|
---|
302 | \param pos Position of the appended point.
|
---|
303 | \sa append(). moved()
|
---|
304 | */
|
---|
305 | void appended(const QPoint &pos);
|
---|
306 |
|
---|
307 | /*!
|
---|
308 | A signal emitted whenever the last appended point of the
|
---|
309 | selection has been moved.
|
---|
310 |
|
---|
311 | \param pos Position of the moved last point of the selection.
|
---|
312 | \sa move(), appended()
|
---|
313 | */
|
---|
314 | void moved(const QPoint &pos);
|
---|
315 |
|
---|
316 | /*!
|
---|
317 | A signal emitted when the active selection has been changed.
|
---|
318 | This might happen when the observed widget is resized.
|
---|
319 |
|
---|
320 | \param pa Changed selection
|
---|
321 | \sa stretchSelection()
|
---|
322 | */
|
---|
323 | void changed(const QwtPolygon &pa);
|
---|
324 |
|
---|
325 | protected:
|
---|
326 | /*!
|
---|
327 | \brief Validate and fixup the selection
|
---|
328 |
|
---|
329 | Accepts all selections unmodified
|
---|
330 |
|
---|
331 | \param selection Selection to validate and fixup
|
---|
332 | \return true, when accepted, false otherwise
|
---|
333 | */
|
---|
334 | virtual bool accept(QwtPolygon &selection) const;
|
---|
335 |
|
---|
336 | virtual void transition(const QEvent *);
|
---|
337 |
|
---|
338 | virtual void begin();
|
---|
339 | virtual void append(const QPoint &);
|
---|
340 | virtual void move(const QPoint &);
|
---|
341 | virtual bool end(bool ok = true);
|
---|
342 |
|
---|
343 | virtual void reset();
|
---|
344 |
|
---|
345 | virtual void widgetMousePressEvent(QMouseEvent *);
|
---|
346 | virtual void widgetMouseReleaseEvent(QMouseEvent *);
|
---|
347 | virtual void widgetMouseDoubleClickEvent(QMouseEvent *);
|
---|
348 | virtual void widgetMouseMoveEvent(QMouseEvent *);
|
---|
349 | virtual void widgetWheelEvent(QWheelEvent *);
|
---|
350 | virtual void widgetKeyPressEvent(QKeyEvent *);
|
---|
351 | virtual void widgetKeyReleaseEvent(QKeyEvent *);
|
---|
352 | virtual void widgetLeaveEvent(QEvent *);
|
---|
353 |
|
---|
354 | virtual void stretchSelection(const QSize &oldSize,
|
---|
355 | const QSize &newSize);
|
---|
356 |
|
---|
357 | virtual QwtPickerMachine *stateMachine(int) const;
|
---|
358 |
|
---|
359 | virtual void updateDisplay();
|
---|
360 |
|
---|
361 | const QWidget *rubberBandWidget() const;
|
---|
362 | const QWidget *trackerWidget() const;
|
---|
363 |
|
---|
364 | private:
|
---|
365 | void init(QWidget *, int selectionFlags, RubberBand rubberBand,
|
---|
366 | DisplayMode trackerMode);
|
---|
367 |
|
---|
368 | void setStateMachine(QwtPickerMachine *);
|
---|
369 | void setMouseTracking(bool);
|
---|
370 |
|
---|
371 | class PickerWidget;
|
---|
372 | class PrivateData;
|
---|
373 | PrivateData *d_data;
|
---|
374 | };
|
---|
375 |
|
---|
376 | #endif
|
---|