Add OpenCV source code
[platform/upstream/opencv.git] / modules / highgui / src / window_QT.h
1 //IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
2
3 // By downloading, copying, installing or using the software you agree to this license.
4 // If you do not agree to this license, do not download, install,
5 // copy or use the software.
6
7
8 //                          License Agreement
9 //               For Open Source Computer Vision Library
10
11 //Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
12 //Copyright (C) 2008-2010, Willow Garage Inc., all rights reserved.
13 //Third party copyrights are property of their respective owners.
14
15 //Redistribution and use in source and binary forms, with or without modification,
16 //are permitted provided that the following conditions are met:
17
18 //  * Redistribution's of source code must retain the above copyright notice,
19 //  this list of conditions and the following disclaimer.
20
21 //  * Redistribution's in binary form must reproduce the above copyright notice,
22 //  this list of conditions and the following disclaimer in the documentation
23 //  and/or other materials provided with the distribution.
24
25 //  * The name of the copyright holders may not be used to endorse or promote products
26 //  derived from this software without specific prior written permission.
27
28 //This software is provided by the copyright holders and contributors "as is" and
29 //any express or implied warranties, including, but not limited to, the implied
30 //warranties of merchantability and fitness for a particular purpose are disclaimed.
31 //In no event shall the Intel Corporation or contributors be liable for any direct,
32 //indirect, incidental, special, exemplary, or consequential damages
33 //(including, but not limited to, procurement of substitute goods or services;
34 //loss of use, data, or profits; or business interruption) however caused
35 //and on any theory of liability, whether in contract, strict liability,
36 //or tort (including negligence or otherwise) arising in any way out of
37 //the use of this software, even if advised of the possibility of such damage.
38
39 //--------------------Google Code 2010 -- Yannick Verdie--------------------//
40 #ifndef __OPENCV_HIGHGUI_QT_H__
41 #define __OPENCV_HIGHGUI_QT_H__
42
43 #include "precomp.hpp"
44
45 #if defined( HAVE_QT_OPENGL )
46 #include <QtOpenGL>
47 #include <QGLWidget>
48 #endif
49
50 #include <QAbstractEventDispatcher>
51 #include <QApplication>
52 #include <QFile>
53 #include <QPushButton>
54 #include <QGraphicsView>
55 #include <QSizePolicy>
56 #include <QInputDialog>
57 #include <QBoxLayout>
58 #include <QSettings>
59 #include <qtimer.h>
60 #include <QtConcurrentRun>
61 #include <QWaitCondition>
62 #include <QKeyEvent>
63 #include <QMetaObject>
64 #include <QPointer>
65 #include <QSlider>
66 #include <QLabel>
67 #include <QIODevice>
68 #include <QShortcut>
69 #include <QStatusBar>
70 #include <QVarLengthArray>
71 #include <QFileInfo>
72 #include <QDate>
73 #include <QFileDialog>
74 #include <QToolBar>
75 #include <QAction>
76 #include <QPushButton>
77 #include <QCheckBox>
78 #include <QRadioButton>
79 #include <QButtonGroup>
80 #include <QMenu>
81 #include <QTest>
82
83 //start private enum
84 enum { CV_MODE_NORMAL = 0, CV_MODE_OPENGL = 1 };
85
86 //we can change the keyboard shortcuts from here !
87 enum {  shortcut_zoom_normal    = Qt::CTRL + Qt::Key_Z,
88         shortcut_zoom_imgRegion = Qt::CTRL + Qt::Key_X,
89         shortcut_save_img               = Qt::CTRL + Qt::Key_S,
90         shortcut_properties_win = Qt::CTRL + Qt::Key_P,
91         shortcut_zoom_in                = Qt::CTRL + Qt::Key_Plus,//QKeySequence(QKeySequence::ZoomIn),
92         shortcut_zoom_out               = Qt::CTRL + Qt::Key_Minus,//QKeySequence(QKeySequence::ZoomOut),
93         shortcut_panning_left   = Qt::CTRL + Qt::Key_Left,
94         shortcut_panning_right  = Qt::CTRL + Qt::Key_Right,
95         shortcut_panning_up     = Qt::CTRL + Qt::Key_Up,
96         shortcut_panning_down   = Qt::CTRL + Qt::Key_Down
97     };
98
99 //end enum
100
101 class CvWindow;
102 class ViewPort;
103
104
105 class GuiReceiver : public QObject
106 {
107     Q_OBJECT
108
109 public:
110     GuiReceiver();
111     ~GuiReceiver();
112
113     int start();
114     void isLastWindow();
115
116     bool bTimeOut;
117     QTimer* timer;
118
119 public slots:
120     void createWindow( QString name, int flags = 0 );
121     void destroyWindow(QString name);
122     void destroyAllWindow();
123     void addSlider(QString trackbar_name, QString window_name, void* value, int count, void* on_change);
124     void addSlider2(QString trackbar_name, QString window_name, void* value, int count, void* on_change, void *userdata);
125     void moveWindow(QString name, int x, int y);
126     void resizeWindow(QString name, int width, int height);
127     void showImage(QString name, void* arr);
128     void displayInfo( QString name, QString text, int delayms );
129     void displayStatusBar( QString name, QString text, int delayms );
130     void timeOut();
131     void toggleFullScreen(QString name, double flags );
132     double isFullScreen(QString name);
133     double getPropWindow(QString name);
134     void setPropWindow(QString name, double flags );
135     double getRatioWindow(QString name);
136     void setRatioWindow(QString name, double arg2 );
137     void saveWindowParameters(QString name);
138     void loadWindowParameters(QString name);
139     void putText(void* arg1, QString text, QPoint org, void* font);
140     void addButton(QString button_name, int button_type, int initial_button_state , void* on_change, void* userdata);
141     void enablePropertiesButtonEachWindow();
142
143     void setOpenGlDrawCallback(QString name, void* callback, void* userdata);
144     void setOpenGlContext(QString name);
145     void updateWindow(QString name);
146     double isOpenGl(QString name);
147
148 private:
149     int nb_windows;
150     bool doesExternalQAppExist;
151 };
152
153
154 enum typeBar { type_CvTrackbar = 0, type_CvButtonbar = 1 };
155 class CvBar : public QHBoxLayout
156 {
157 public:
158     typeBar type;
159     QString name_bar;
160     QPointer<QWidget> myparent;
161 };
162
163
164 class CvButtonbar : public CvBar
165 {
166     Q_OBJECT
167 public:
168     CvButtonbar(QWidget* arg, QString bar_name);
169
170     void addButton(QString button_name, CvButtonCallback call, void* userdata,  int button_type, int initial_button_state);
171
172 private:
173     void setLabel();
174
175     QPointer<QLabel> label;
176     QPointer<QButtonGroup> group_button;
177 };
178
179
180 class CvPushButton : public QPushButton
181 {
182     Q_OBJECT
183 public:
184     CvPushButton(CvButtonbar* par, QString button_name, CvButtonCallback call, void* userdata);
185
186 private:
187     CvButtonbar* myparent;
188     QString button_name ;
189     CvButtonCallback callback;
190     void* userdata;
191
192 private slots:
193     void callCallBack(bool);
194 };
195
196
197 class CvCheckBox : public QCheckBox
198 {
199     Q_OBJECT
200 public:
201     CvCheckBox(CvButtonbar* par, QString button_name, CvButtonCallback call, void* userdata, int initial_button_state);
202
203 private:
204     CvButtonbar* myparent;
205     QString button_name ;
206     CvButtonCallback callback;
207     void* userdata;
208
209 private slots:
210     void callCallBack(bool);
211 };
212
213
214 class CvRadioButton : public QRadioButton
215 {
216     Q_OBJECT
217 public:
218     CvRadioButton(CvButtonbar* par, QString button_name, CvButtonCallback call, void* userdata, int initial_button_state);
219
220 private:
221     CvButtonbar* myparent;
222     QString button_name ;
223     CvButtonCallback callback;
224     void* userdata;
225
226 private slots:
227     void callCallBack(bool);
228 };
229
230
231 class CvTrackbar :  public CvBar
232 {
233     Q_OBJECT
234 public:
235     CvTrackbar(CvWindow* parent, QString name, int* value, int count, CvTrackbarCallback on_change);
236     CvTrackbar(CvWindow* parent, QString name, int* value, int count, CvTrackbarCallback2 on_change, void* data);
237
238     QPointer<QSlider> slider;
239
240 private slots:
241     void createDialog();
242     void update(int myvalue);
243
244 private:
245     void setLabel(int myvalue);
246     void create(CvWindow* arg, QString name, int* value, int count);
247     QString createLabel();
248     QPointer<QPushButton > label;
249     CvTrackbarCallback callback;
250     CvTrackbarCallback2 callback2;//look like it is use by python binding
251     int* dataSlider;
252     void* userdata;
253 };
254
255 //Both are top level window, so that a way to differenciate them.
256 //if (obj->metaObject ()->className () == "CvWindow") does not give me robust result
257
258 enum typeWindow { type_CvWindow = 1, type_CvWinProperties = 2 };
259 class CvWinModel : public QWidget
260 {
261 public:
262 typeWindow type;
263 };
264
265
266 class CvWinProperties : public CvWinModel
267 {
268     Q_OBJECT
269 public:
270     CvWinProperties(QString name, QObject* parent);
271     ~CvWinProperties();
272     QPointer<QBoxLayout> myLayout;
273
274 private:
275     void closeEvent ( QCloseEvent * e );
276     void showEvent ( QShowEvent * event ) ;
277     void hideEvent ( QHideEvent * event ) ;
278 };
279
280
281 class CvWindow : public CvWinModel
282 {
283     Q_OBJECT
284 public:
285     CvWindow(QString arg2, int flag = CV_WINDOW_NORMAL);
286     ~CvWindow();
287
288     void setMouseCallBack(CvMouseCallback m, void* param);
289
290     void writeSettings();
291     void readSettings();
292
293     double getRatio();
294     void setRatio(int flags);
295
296     int getPropWindow();
297     void setPropWindow(int flags);
298
299     void toggleFullScreen(int flags);
300
301     void updateImage(void* arr);
302
303     void displayInfo(QString text, int delayms);
304     void displayStatusBar(QString text, int delayms);
305
306     void enablePropertiesButton();
307
308     static CvButtonbar* createButtonBar(QString bar_name);
309
310     static void addSlider(CvWindow* w, QString name, int* value, int count, CvTrackbarCallback on_change CV_DEFAULT(NULL));
311     static void addSlider2(CvWindow* w, QString name, int* value, int count, CvTrackbarCallback2 on_change CV_DEFAULT(NULL), void* userdata CV_DEFAULT(0));
312
313     void setOpenGlDrawCallback(CvOpenGlDrawCallback callback, void* userdata);
314     void makeCurrentOpenGlContext();
315     void updateGl();
316     bool isOpenGl();
317
318     void setViewportSize(QSize size);
319
320     //parameters (will be save/load)
321     int param_flags;
322     int param_gui_mode;
323     int param_ratio_mode;
324
325     QPointer<QBoxLayout> myGlobalLayout; //All the widget (toolbar, view, LayoutBar, ...) are attached to it
326     QPointer<QBoxLayout> myBarLayout;
327
328     QVector<QAction*> vect_QActions;
329
330     QPointer<QStatusBar> myStatusBar;
331     QPointer<QToolBar> myToolBar;
332     QPointer<QLabel> myStatusBar_msg;
333
334 protected:
335     virtual void keyPressEvent(QKeyEvent* event);
336
337 private:
338
339     int mode_display; //opengl or native
340     ViewPort* myView;
341
342     QVector<QShortcut*> vect_QShortcuts;
343
344     void icvLoadTrackbars(QSettings *settings);
345     void icvSaveTrackbars(QSettings *settings);
346     void icvLoadControlPanel();
347     void icvSaveControlPanel();
348     void icvLoadButtonbar(CvButtonbar* t,QSettings *settings);
349     void icvSaveButtonbar(CvButtonbar* t,QSettings *settings);
350
351     void createActions();
352     void createShortcuts();
353     void createToolBar();
354     void createView();
355     void createStatusBar();
356     void createGlobalLayout();
357     void createBarLayout();
358     CvWinProperties* createParameterWindow();
359
360     void hideTools();
361     void showTools();
362     QSize getAvailableSize();
363
364 private slots:
365     void displayPropertiesWin();
366 };
367
368
369 enum type_mouse_event { mouse_up = 0, mouse_down = 1, mouse_dbclick = 2, mouse_move = 3 };
370 static const int tableMouseButtons[][3]={
371     {CV_EVENT_LBUTTONUP, CV_EVENT_RBUTTONUP, CV_EVENT_MBUTTONUP},               //mouse_up
372     {CV_EVENT_LBUTTONDOWN, CV_EVENT_RBUTTONDOWN, CV_EVENT_MBUTTONDOWN},         //mouse_down
373     {CV_EVENT_LBUTTONDBLCLK, CV_EVENT_RBUTTONDBLCLK, CV_EVENT_MBUTTONDBLCLK},   //mouse_dbclick
374     {CV_EVENT_MOUSEMOVE, CV_EVENT_MOUSEMOVE, CV_EVENT_MOUSEMOVE}                //mouse_move
375 };
376
377
378 class ViewPort
379 {
380 public:
381     virtual ~ViewPort() {}
382
383     virtual QWidget* getWidget() = 0;
384
385     virtual void setMouseCallBack(CvMouseCallback callback, void* param) = 0;
386
387     virtual void writeSettings(QSettings& settings) = 0;
388     virtual void readSettings(QSettings& settings) = 0;
389
390     virtual double getRatio() = 0;
391     virtual void setRatio(int flags) = 0;
392
393     virtual void updateImage(const CvArr* arr) = 0;
394
395     virtual void startDisplayInfo(QString text, int delayms) = 0;
396
397     virtual void setOpenGlDrawCallback(CvOpenGlDrawCallback callback, void* userdata) = 0;
398     virtual void makeCurrentOpenGlContext() = 0;
399     virtual void updateGl() = 0;
400
401     virtual void setSize(QSize size_) = 0;
402 };
403
404
405
406 #ifdef HAVE_QT_OPENGL
407
408 class OpenGlViewPort : public QGLWidget, public ViewPort
409 {
410 public:
411     explicit OpenGlViewPort(QWidget* parent);
412     ~OpenGlViewPort();
413
414     QWidget* getWidget();
415
416     void setMouseCallBack(CvMouseCallback callback, void* param);
417
418     void writeSettings(QSettings& settings);
419     void readSettings(QSettings& settings);
420
421     double getRatio();
422     void setRatio(int flags);
423
424     void updateImage(const CvArr* arr);
425
426     void startDisplayInfo(QString text, int delayms);
427
428     void setOpenGlDrawCallback(CvOpenGlDrawCallback callback, void* userdata);
429     void makeCurrentOpenGlContext();
430     void updateGl();
431
432     void setSize(QSize size_);
433
434 protected:
435     void initializeGL();
436     void resizeGL(int w, int h);
437     void paintGL();
438
439     void mouseMoveEvent(QMouseEvent* event);
440     void mousePressEvent(QMouseEvent* event);
441     void mouseReleaseEvent(QMouseEvent* event);
442     void mouseDoubleClickEvent(QMouseEvent* event);
443
444     QSize sizeHint() const;
445
446 private:
447     QSize size;
448
449     CvMouseCallback mouseCallback;
450     void* mouseData;
451
452     CvOpenGlDrawCallback glDrawCallback;
453     void* glDrawData;
454
455     void icvmouseHandler(QMouseEvent* event, type_mouse_event category, int& cv_event, int& flags);
456     void icvmouseProcessing(QPointF pt, int cv_event, int flags);
457 };
458
459 #endif // HAVE_QT_OPENGL
460
461
462 class DefaultViewPort : public QGraphicsView, public ViewPort
463 {
464     Q_OBJECT
465
466 public:
467     DefaultViewPort(CvWindow* centralWidget, int arg2);
468     ~DefaultViewPort();
469
470     QWidget* getWidget();
471
472     void setMouseCallBack(CvMouseCallback callback, void* param);
473
474     void writeSettings(QSettings& settings);
475     void readSettings(QSettings& settings);
476
477     double getRatio();
478     void setRatio(int flags);
479
480     void updateImage(const CvArr* arr);
481
482     void startDisplayInfo(QString text, int delayms);
483
484     void setOpenGlDrawCallback(CvOpenGlDrawCallback callback, void* userdata);
485     void makeCurrentOpenGlContext();
486     void updateGl();
487
488     void setSize(QSize size_);
489
490 public slots:
491     //reference:
492     //http://www.qtcentre.org/wiki/index.php?title=QGraphicsView:_Smooth_Panning_and_Zooming
493     //http://doc.qt.nokia.com/4.6/gestures-imagegestures-imagewidget-cpp.html
494
495     void siftWindowOnLeft();
496     void siftWindowOnRight();
497     void siftWindowOnUp() ;
498     void siftWindowOnDown();
499
500     void resetZoom();
501     void imgRegion();
502     void ZoomIn();
503     void ZoomOut();
504
505     void saveView();
506
507 protected:
508     void contextMenuEvent(QContextMenuEvent* event);
509     void resizeEvent(QResizeEvent* event);
510     void paintEvent(QPaintEvent* paintEventInfo);
511     void wheelEvent(QWheelEvent* event);
512     void mouseMoveEvent(QMouseEvent* event);
513     void mousePressEvent(QMouseEvent* event);
514     void mouseReleaseEvent(QMouseEvent* event);
515     void mouseDoubleClickEvent(QMouseEvent* event);
516
517 private:
518     int param_keepRatio;
519
520     //parameters (will be save/load)
521     QTransform param_matrixWorld;
522
523     CvMat* image2Draw_mat;
524     QImage image2Draw_qt;
525     int nbChannelOriginImage;
526
527     //for mouse callback
528     CvMouseCallback on_mouse;
529     void* on_mouse_param;
530
531
532     void scaleView(qreal scaleFactor, QPointF center);
533     void moveView(QPointF delta);
534
535     QPoint mouseCoordinate;
536     QPointF positionGrabbing;
537     QRect  positionCorners;
538     QTransform matrixWorld_inv;
539     float ratioX, ratioY;
540
541     bool isSameSize(IplImage* img1,IplImage* img2);
542
543     QSize sizeHint() const;
544     QPointer<CvWindow> centralWidget;
545     QPointer<QTimer> timerDisplay;
546     bool drawInfo;
547     QString infoText;
548     QRectF target;
549
550     void drawInstructions(QPainter *painter);
551     void drawViewOverview(QPainter *painter);
552     void drawImgRegion(QPainter *painter);
553     void draw2D(QPainter *painter);
554     void drawStatusBar();
555     void controlImagePosition();
556     void icvmouseHandler(QMouseEvent *event, type_mouse_event category, int &cv_event, int &flags);
557     void icvmouseProcessing(QPointF pt, int cv_event, int flags);
558
559 private slots:
560     void stopDisplayInfo();
561 };
562
563 #endif