Home | History | Annotate | Download | only in src
      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     void setWindowTitle(QString name, QString title);
    136     double getRatioWindow(QString name);
    137     void setRatioWindow(QString name, double arg2 );
    138     void saveWindowParameters(QString name);
    139     void loadWindowParameters(QString name);
    140     void putText(void* arg1, QString text, QPoint org, void* font);
    141     void addButton(QString button_name, int button_type, int initial_button_state , void* on_change, void* userdata);
    142     void enablePropertiesButtonEachWindow();
    143 
    144     void setOpenGlDrawCallback(QString name, void* callback, void* userdata);
    145     void setOpenGlContext(QString name);
    146     void updateWindow(QString name);
    147     double isOpenGl(QString name);
    148 
    149 private:
    150     int nb_windows;
    151     bool doesExternalQAppExist;
    152 };
    153 
    154 
    155 enum typeBar { type_CvTrackbar = 0, type_CvButtonbar = 1 };
    156 class CvBar : public QHBoxLayout
    157 {
    158 public:
    159     typeBar type;
    160     QString name_bar;
    161     QPointer<QWidget> myparent;
    162 };
    163 
    164 
    165 class CvButtonbar : public CvBar
    166 {
    167     Q_OBJECT
    168 public:
    169     CvButtonbar(QWidget* arg, QString bar_name);
    170 
    171     void addButton(QString button_name, CvButtonCallback call, void* userdata,  int button_type, int initial_button_state);
    172 
    173 private:
    174     void setLabel();
    175 
    176     QPointer<QLabel> label;
    177     QPointer<QButtonGroup> group_button;
    178 };
    179 
    180 
    181 class CvPushButton : public QPushButton
    182 {
    183     Q_OBJECT
    184 public:
    185     CvPushButton(CvButtonbar* par, QString button_name, CvButtonCallback call, void* userdata);
    186 
    187 private:
    188     CvButtonbar* myparent;
    189     QString button_name ;
    190     CvButtonCallback callback;
    191     void* userdata;
    192 
    193 private slots:
    194     void callCallBack(bool);
    195 };
    196 
    197 
    198 class CvCheckBox : public QCheckBox
    199 {
    200     Q_OBJECT
    201 public:
    202     CvCheckBox(CvButtonbar* par, QString button_name, CvButtonCallback call, void* userdata, int initial_button_state);
    203 
    204 private:
    205     CvButtonbar* myparent;
    206     QString button_name ;
    207     CvButtonCallback callback;
    208     void* userdata;
    209 
    210 private slots:
    211     void callCallBack(bool);
    212 };
    213 
    214 
    215 class CvRadioButton : public QRadioButton
    216 {
    217     Q_OBJECT
    218 public:
    219     CvRadioButton(CvButtonbar* par, QString button_name, CvButtonCallback call, void* userdata, int initial_button_state);
    220 
    221 private:
    222     CvButtonbar* myparent;
    223     QString button_name ;
    224     CvButtonCallback callback;
    225     void* userdata;
    226 
    227 private slots:
    228     void callCallBack(bool);
    229 };
    230 
    231 
    232 class CvTrackbar :  public CvBar
    233 {
    234     Q_OBJECT
    235 public:
    236     CvTrackbar(CvWindow* parent, QString name, int* value, int count, CvTrackbarCallback on_change);
    237     CvTrackbar(CvWindow* parent, QString name, int* value, int count, CvTrackbarCallback2 on_change, void* data);
    238 
    239     QPointer<QSlider> slider;
    240 
    241 private slots:
    242     void createDialog();
    243     void update(int myvalue);
    244 
    245 private:
    246     void setLabel(int myvalue);
    247     void create(CvWindow* arg, QString name, int* value, int count);
    248     QString createLabel();
    249     QPointer<QPushButton > label;
    250     CvTrackbarCallback callback;
    251     CvTrackbarCallback2 callback2;//look like it is use by python binding
    252     int* dataSlider;
    253     void* userdata;
    254 };
    255 
    256 //Both are top level window, so that a way to differenciate them.
    257 //if (obj->metaObject ()->className () == "CvWindow") does not give me robust result
    258 
    259 enum typeWindow { type_CvWindow = 1, type_CvWinProperties = 2 };
    260 class CvWinModel : public QWidget
    261 {
    262 public:
    263 typeWindow type;
    264 };
    265 
    266 
    267 class CvWinProperties : public CvWinModel
    268 {
    269     Q_OBJECT
    270 public:
    271     CvWinProperties(QString name, QObject* parent);
    272     ~CvWinProperties();
    273     QPointer<QBoxLayout> myLayout;
    274 
    275 private:
    276     void closeEvent ( QCloseEvent * e );
    277     void showEvent ( QShowEvent * event ) ;
    278     void hideEvent ( QHideEvent * event ) ;
    279 };
    280 
    281 
    282 class CvWindow : public CvWinModel
    283 {
    284     Q_OBJECT
    285 public:
    286     CvWindow(QString arg2, int flag = CV_WINDOW_NORMAL);
    287     ~CvWindow();
    288 
    289     void setMouseCallBack(CvMouseCallback m, void* param);
    290 
    291     void writeSettings();
    292     void readSettings();
    293 
    294     double getRatio();
    295     void setRatio(int flags);
    296 
    297     int getPropWindow();
    298     void setPropWindow(int flags);
    299 
    300     void toggleFullScreen(int flags);
    301 
    302     void updateImage(void* arr);
    303 
    304     void displayInfo(QString text, int delayms);
    305     void displayStatusBar(QString text, int delayms);
    306 
    307     void enablePropertiesButton();
    308 
    309     static CvButtonbar* createButtonBar(QString bar_name);
    310 
    311     static void addSlider(CvWindow* w, QString name, int* value, int count, CvTrackbarCallback on_change CV_DEFAULT(NULL));
    312     static void addSlider2(CvWindow* w, QString name, int* value, int count, CvTrackbarCallback2 on_change CV_DEFAULT(NULL), void* userdata CV_DEFAULT(0));
    313 
    314     void setOpenGlDrawCallback(CvOpenGlDrawCallback callback, void* userdata);
    315     void makeCurrentOpenGlContext();
    316     void updateGl();
    317     bool isOpenGl();
    318 
    319     void setViewportSize(QSize size);
    320 
    321     //parameters (will be save/load)
    322     int param_flags;
    323     int param_gui_mode;
    324     int param_ratio_mode;
    325 
    326     QPointer<QBoxLayout> myGlobalLayout; //All the widget (toolbar, view, LayoutBar, ...) are attached to it
    327     QPointer<QBoxLayout> myBarLayout;
    328 
    329     QVector<QAction*> vect_QActions;
    330 
    331     QPointer<QStatusBar> myStatusBar;
    332     QPointer<QToolBar> myToolBar;
    333     QPointer<QLabel> myStatusBar_msg;
    334 
    335 protected:
    336     virtual void keyPressEvent(QKeyEvent* event);
    337 
    338 private:
    339 
    340     int mode_display; //opengl or native
    341     ViewPort* myView;
    342 
    343     QVector<QShortcut*> vect_QShortcuts;
    344 
    345     void icvLoadTrackbars(QSettings *settings);
    346     void icvSaveTrackbars(QSettings *settings);
    347     void icvLoadControlPanel();
    348     void icvSaveControlPanel();
    349     void icvLoadButtonbar(CvButtonbar* t,QSettings *settings);
    350     void icvSaveButtonbar(CvButtonbar* t,QSettings *settings);
    351 
    352     void createActions();
    353     void createShortcuts();
    354     void createToolBar();
    355     void createView();
    356     void createStatusBar();
    357     void createGlobalLayout();
    358     void createBarLayout();
    359     CvWinProperties* createParameterWindow();
    360 
    361     void hideTools();
    362     void showTools();
    363     QSize getAvailableSize();
    364 
    365 private slots:
    366     void displayPropertiesWin();
    367 };
    368 
    369 
    370 enum type_mouse_event { mouse_up = 0, mouse_down = 1, mouse_dbclick = 2, mouse_move = 3 };
    371 static const int tableMouseButtons[][3]={
    372     {CV_EVENT_LBUTTONUP, CV_EVENT_RBUTTONUP, CV_EVENT_MBUTTONUP},               //mouse_up
    373     {CV_EVENT_LBUTTONDOWN, CV_EVENT_RBUTTONDOWN, CV_EVENT_MBUTTONDOWN},         //mouse_down
    374     {CV_EVENT_LBUTTONDBLCLK, CV_EVENT_RBUTTONDBLCLK, CV_EVENT_MBUTTONDBLCLK},   //mouse_dbclick
    375     {CV_EVENT_MOUSEMOVE, CV_EVENT_MOUSEMOVE, CV_EVENT_MOUSEMOVE}                //mouse_move
    376 };
    377 
    378 
    379 class ViewPort
    380 {
    381 public:
    382     virtual ~ViewPort() {}
    383 
    384     virtual QWidget* getWidget() = 0;
    385 
    386     virtual void setMouseCallBack(CvMouseCallback callback, void* param) = 0;
    387 
    388     virtual void writeSettings(QSettings& settings) = 0;
    389     virtual void readSettings(QSettings& settings) = 0;
    390 
    391     virtual double getRatio() = 0;
    392     virtual void setRatio(int flags) = 0;
    393 
    394     virtual void updateImage(const CvArr* arr) = 0;
    395 
    396     virtual void startDisplayInfo(QString text, int delayms) = 0;
    397 
    398     virtual void setOpenGlDrawCallback(CvOpenGlDrawCallback callback, void* userdata) = 0;
    399     virtual void makeCurrentOpenGlContext() = 0;
    400     virtual void updateGl() = 0;
    401 
    402     virtual void setSize(QSize size_) = 0;
    403 };
    404 
    405 
    406 
    407 #ifdef HAVE_QT_OPENGL
    408 
    409 class OpenGlViewPort : public QGLWidget, public ViewPort
    410 {
    411 public:
    412     explicit OpenGlViewPort(QWidget* parent);
    413     ~OpenGlViewPort();
    414 
    415     QWidget* getWidget();
    416 
    417     void setMouseCallBack(CvMouseCallback callback, void* param);
    418 
    419     void writeSettings(QSettings& settings);
    420     void readSettings(QSettings& settings);
    421 
    422     double getRatio();
    423     void setRatio(int flags);
    424 
    425     void updateImage(const CvArr* arr);
    426 
    427     void startDisplayInfo(QString text, int delayms);
    428 
    429     void setOpenGlDrawCallback(CvOpenGlDrawCallback callback, void* userdata);
    430     void makeCurrentOpenGlContext();
    431     void updateGl();
    432 
    433     void setSize(QSize size_);
    434 
    435 protected:
    436     void initializeGL();
    437     void resizeGL(int w, int h);
    438     void paintGL();
    439 
    440     void mouseMoveEvent(QMouseEvent* event);
    441     void mousePressEvent(QMouseEvent* event);
    442     void mouseReleaseEvent(QMouseEvent* event);
    443     void mouseDoubleClickEvent(QMouseEvent* event);
    444 
    445     QSize sizeHint() const;
    446 
    447 private:
    448     QSize size;
    449 
    450     CvMouseCallback mouseCallback;
    451     void* mouseData;
    452 
    453     CvOpenGlDrawCallback glDrawCallback;
    454     void* glDrawData;
    455 
    456     void icvmouseHandler(QMouseEvent* event, type_mouse_event category, int& cv_event, int& flags);
    457     void icvmouseProcessing(QPointF pt, int cv_event, int flags);
    458 };
    459 
    460 #endif // HAVE_QT_OPENGL
    461 
    462 
    463 class DefaultViewPort : public QGraphicsView, public ViewPort
    464 {
    465     Q_OBJECT
    466 
    467 public:
    468     DefaultViewPort(CvWindow* centralWidget, int arg2);
    469     ~DefaultViewPort();
    470 
    471     QWidget* getWidget();
    472 
    473     void setMouseCallBack(CvMouseCallback callback, void* param);
    474 
    475     void writeSettings(QSettings& settings);
    476     void readSettings(QSettings& settings);
    477 
    478     double getRatio();
    479     void setRatio(int flags);
    480 
    481     void updateImage(const CvArr* arr);
    482 
    483     void startDisplayInfo(QString text, int delayms);
    484 
    485     void setOpenGlDrawCallback(CvOpenGlDrawCallback callback, void* userdata);
    486     void makeCurrentOpenGlContext();
    487     void updateGl();
    488 
    489     void setSize(QSize size_);
    490 
    491 public slots:
    492     //reference:
    493     //http://www.qtcentre.org/wiki/index.php?title=QGraphicsView:_Smooth_Panning_and_Zooming
    494     //http://doc.qt.nokia.com/4.6/gestures-imagegestures-imagewidget-cpp.html
    495 
    496     void siftWindowOnLeft();
    497     void siftWindowOnRight();
    498     void siftWindowOnUp() ;
    499     void siftWindowOnDown();
    500 
    501     void resetZoom();
    502     void imgRegion();
    503     void ZoomIn();
    504     void ZoomOut();
    505 
    506     void saveView();
    507 
    508 protected:
    509     void contextMenuEvent(QContextMenuEvent* event);
    510     void resizeEvent(QResizeEvent* event);
    511     void paintEvent(QPaintEvent* paintEventInfo);
    512     void wheelEvent(QWheelEvent* event);
    513     void mouseMoveEvent(QMouseEvent* event);
    514     void mousePressEvent(QMouseEvent* event);
    515     void mouseReleaseEvent(QMouseEvent* event);
    516     void mouseDoubleClickEvent(QMouseEvent* event);
    517 
    518 private:
    519     int param_keepRatio;
    520 
    521     //parameters (will be save/load)
    522     QTransform param_matrixWorld;
    523 
    524     CvMat* image2Draw_mat;
    525     QImage image2Draw_qt;
    526     int nbChannelOriginImage;
    527 
    528     //for mouse callback
    529     CvMouseCallback on_mouse;
    530     void* on_mouse_param;
    531 
    532 
    533     void scaleView(qreal scaleFactor, QPointF center);
    534     void moveView(QPointF delta);
    535 
    536     QPoint mouseCoordinate;
    537     QPointF positionGrabbing;
    538     QRect  positionCorners;
    539     QTransform matrixWorld_inv;
    540     float ratioX, ratioY;
    541 
    542     bool isSameSize(IplImage* img1,IplImage* img2);
    543 
    544     QSize sizeHint() const;
    545     QPointer<CvWindow> centralWidget;
    546     QPointer<QTimer> timerDisplay;
    547     bool drawInfo;
    548     QString infoText;
    549     QRectF target;
    550 
    551     void drawInstructions(QPainter *painter);
    552     void drawViewOverview(QPainter *painter);
    553     void drawImgRegion(QPainter *painter);
    554     void draw2D(QPainter *painter);
    555     void drawStatusBar();
    556     void controlImagePosition();
    557     void icvmouseHandler(QMouseEvent *event, type_mouse_event category, int &cv_event, int &flags);
    558     void icvmouseProcessing(QPointF pt, int cv_event, int flags);
    559 
    560 private slots:
    561     void stopDisplayInfo();
    562 };
    563 
    564 #endif
    565