//IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. // By downloading, copying, installing or using the software you agree to this license. // If you do not agree to this license, do not download, install, // copy or use the software. // License Agreement // For Open Source Computer Vision Library //Copyright (C) 2000-2008, Intel Corporation, all rights reserved. //Copyright (C) 2008-2010, Willow Garage Inc., all rights reserved. //Third party copyrights are property of their respective owners. //Redistribution and use in source and binary forms, with or without modification, //are permitted provided that the following conditions are met: // * Redistribution's of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // * Redistribution's in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // * The name of the copyright holders may not be used to endorse or promote products // derived from this software without specific prior written permission. //This software is provided by the copyright holders and contributors "as is" and //any express or implied warranties, including, but not limited to, the implied //warranties of merchantability and fitness for a particular purpose are disclaimed. //In no event shall the Intel Corporation or contributors be liable for any direct, //indirect, incidental, special, exemplary, or consequential damages //(including, but not limited to, procurement of substitute goods or services; //loss of use, data, or profits; or business interruption) however caused //and on any theory of liability, whether in contract, strict liability, //or tort (including negligence or otherwise) arising in any way out of //the use of this software, even if advised of the possibility of such damage. //--------------------Google Code 2010 -- Yannick Verdie--------------------// #ifndef __OPENCV_HIGHGUI_QT_H__ #define __OPENCV_HIGHGUI_QT_H__ #include "precomp.hpp" #if defined( HAVE_QT_OPENGL ) #include #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //start private enum enum { CV_MODE_NORMAL = 0, CV_MODE_OPENGL = 1 }; //we can change the keyboard shortcuts from here ! enum { shortcut_zoom_normal = Qt::CTRL + Qt::Key_Z, shortcut_zoom_imgRegion = Qt::CTRL + Qt::Key_X, shortcut_save_img = Qt::CTRL + Qt::Key_S, shortcut_properties_win = Qt::CTRL + Qt::Key_P, shortcut_zoom_in = Qt::CTRL + Qt::Key_Plus,//QKeySequence(QKeySequence::ZoomIn), shortcut_zoom_out = Qt::CTRL + Qt::Key_Minus,//QKeySequence(QKeySequence::ZoomOut), shortcut_panning_left = Qt::CTRL + Qt::Key_Left, shortcut_panning_right = Qt::CTRL + Qt::Key_Right, shortcut_panning_up = Qt::CTRL + Qt::Key_Up, shortcut_panning_down = Qt::CTRL + Qt::Key_Down }; //end enum class CvWindow; class ViewPort; class GuiReceiver : public QObject { Q_OBJECT public: GuiReceiver(); ~GuiReceiver(); int start(); void isLastWindow(); bool bTimeOut; QTimer* timer; public slots: void createWindow( QString name, int flags = 0 ); void destroyWindow(QString name); void destroyAllWindow(); void addSlider(QString trackbar_name, QString window_name, void* value, int count, void* on_change); void addSlider2(QString trackbar_name, QString window_name, void* value, int count, void* on_change, void *userdata); void moveWindow(QString name, int x, int y); void resizeWindow(QString name, int width, int height); void showImage(QString name, void* arr); void displayInfo( QString name, QString text, int delayms ); void displayStatusBar( QString name, QString text, int delayms ); void timeOut(); void toggleFullScreen(QString name, double flags ); double isFullScreen(QString name); double getPropWindow(QString name); void setPropWindow(QString name, double flags ); double getRatioWindow(QString name); void setRatioWindow(QString name, double arg2 ); void saveWindowParameters(QString name); void loadWindowParameters(QString name); void putText(void* arg1, QString text, QPoint org, void* font); void addButton(QString button_name, int button_type, int initial_button_state , void* on_change, void* userdata); void enablePropertiesButtonEachWindow(); void setOpenGlDrawCallback(QString name, void* callback, void* userdata); void setOpenGlContext(QString name); void updateWindow(QString name); double isOpenGl(QString name); private: int nb_windows; bool doesExternalQAppExist; }; enum typeBar { type_CvTrackbar = 0, type_CvButtonbar = 1 }; class CvBar : public QHBoxLayout { public: typeBar type; QString name_bar; QPointer myparent; }; class CvButtonbar : public CvBar { Q_OBJECT public: CvButtonbar(QWidget* arg, QString bar_name); void addButton(QString button_name, CvButtonCallback call, void* userdata, int button_type, int initial_button_state); private: void setLabel(); QPointer label; QPointer group_button; }; class CvPushButton : public QPushButton { Q_OBJECT public: CvPushButton(CvButtonbar* par, QString button_name, CvButtonCallback call, void* userdata); private: CvButtonbar* myparent; QString button_name ; CvButtonCallback callback; void* userdata; private slots: void callCallBack(bool); }; class CvCheckBox : public QCheckBox { Q_OBJECT public: CvCheckBox(CvButtonbar* par, QString button_name, CvButtonCallback call, void* userdata, int initial_button_state); private: CvButtonbar* myparent; QString button_name ; CvButtonCallback callback; void* userdata; private slots: void callCallBack(bool); }; class CvRadioButton : public QRadioButton { Q_OBJECT public: CvRadioButton(CvButtonbar* par, QString button_name, CvButtonCallback call, void* userdata, int initial_button_state); private: CvButtonbar* myparent; QString button_name ; CvButtonCallback callback; void* userdata; private slots: void callCallBack(bool); }; class CvTrackbar : public CvBar { Q_OBJECT public: CvTrackbar(CvWindow* parent, QString name, int* value, int count, CvTrackbarCallback on_change); CvTrackbar(CvWindow* parent, QString name, int* value, int count, CvTrackbarCallback2 on_change, void* data); QPointer slider; private slots: void createDialog(); void update(int myvalue); private: void setLabel(int myvalue); void create(CvWindow* arg, QString name, int* value, int count); QString createLabel(); QPointer label; CvTrackbarCallback callback; CvTrackbarCallback2 callback2;//look like it is use by python binding int* dataSlider; void* userdata; }; //Both are top level window, so that a way to differenciate them. //if (obj->metaObject ()->className () == "CvWindow") does not give me robust result enum typeWindow { type_CvWindow = 1, type_CvWinProperties = 2 }; class CvWinModel : public QWidget { public: typeWindow type; }; class CvWinProperties : public CvWinModel { Q_OBJECT public: CvWinProperties(QString name, QObject* parent); ~CvWinProperties(); QPointer myLayout; private: void closeEvent ( QCloseEvent * e ); void showEvent ( QShowEvent * event ) ; void hideEvent ( QHideEvent * event ) ; }; class CvWindow : public CvWinModel { Q_OBJECT public: CvWindow(QString arg2, int flag = CV_WINDOW_NORMAL); ~CvWindow(); void setMouseCallBack(CvMouseCallback m, void* param); void writeSettings(); void readSettings(); double getRatio(); void setRatio(int flags); int getPropWindow(); void setPropWindow(int flags); void toggleFullScreen(int flags); void updateImage(void* arr); void displayInfo(QString text, int delayms); void displayStatusBar(QString text, int delayms); void enablePropertiesButton(); static CvButtonbar* createButtonBar(QString bar_name); static void addSlider(CvWindow* w, QString name, int* value, int count, CvTrackbarCallback on_change CV_DEFAULT(NULL)); static void addSlider2(CvWindow* w, QString name, int* value, int count, CvTrackbarCallback2 on_change CV_DEFAULT(NULL), void* userdata CV_DEFAULT(0)); void setOpenGlDrawCallback(CvOpenGlDrawCallback callback, void* userdata); void makeCurrentOpenGlContext(); void updateGl(); bool isOpenGl(); void setViewportSize(QSize size); //parameters (will be save/load) int param_flags; int param_gui_mode; int param_ratio_mode; QPointer myGlobalLayout; //All the widget (toolbar, view, LayoutBar, ...) are attached to it QPointer myBarLayout; QVector vect_QActions; QPointer myStatusBar; QPointer myToolBar; QPointer myStatusBar_msg; protected: virtual void keyPressEvent(QKeyEvent* event); private: int mode_display; //opengl or native ViewPort* myView; QVector vect_QShortcuts; void icvLoadTrackbars(QSettings *settings); void icvSaveTrackbars(QSettings *settings); void icvLoadControlPanel(); void icvSaveControlPanel(); void icvLoadButtonbar(CvButtonbar* t,QSettings *settings); void icvSaveButtonbar(CvButtonbar* t,QSettings *settings); void createActions(); void createShortcuts(); void createToolBar(); void createView(); void createStatusBar(); void createGlobalLayout(); void createBarLayout(); CvWinProperties* createParameterWindow(); void hideTools(); void showTools(); QSize getAvailableSize(); private slots: void displayPropertiesWin(); }; enum type_mouse_event { mouse_up = 0, mouse_down = 1, mouse_dbclick = 2, mouse_move = 3 }; static const int tableMouseButtons[][3]={ {CV_EVENT_LBUTTONUP, CV_EVENT_RBUTTONUP, CV_EVENT_MBUTTONUP}, //mouse_up {CV_EVENT_LBUTTONDOWN, CV_EVENT_RBUTTONDOWN, CV_EVENT_MBUTTONDOWN}, //mouse_down {CV_EVENT_LBUTTONDBLCLK, CV_EVENT_RBUTTONDBLCLK, CV_EVENT_MBUTTONDBLCLK}, //mouse_dbclick {CV_EVENT_MOUSEMOVE, CV_EVENT_MOUSEMOVE, CV_EVENT_MOUSEMOVE} //mouse_move }; class ViewPort { public: virtual ~ViewPort() {} virtual QWidget* getWidget() = 0; virtual void setMouseCallBack(CvMouseCallback callback, void* param) = 0; virtual void writeSettings(QSettings& settings) = 0; virtual void readSettings(QSettings& settings) = 0; virtual double getRatio() = 0; virtual void setRatio(int flags) = 0; virtual void updateImage(const CvArr* arr) = 0; virtual void startDisplayInfo(QString text, int delayms) = 0; virtual void setOpenGlDrawCallback(CvOpenGlDrawCallback callback, void* userdata) = 0; virtual void makeCurrentOpenGlContext() = 0; virtual void updateGl() = 0; virtual void setSize(QSize size_) = 0; }; #ifdef HAVE_QT_OPENGL class OpenGlViewPort : public QGLWidget, public ViewPort { public: explicit OpenGlViewPort(QWidget* parent); ~OpenGlViewPort(); QWidget* getWidget(); void setMouseCallBack(CvMouseCallback callback, void* param); void writeSettings(QSettings& settings); void readSettings(QSettings& settings); double getRatio(); void setRatio(int flags); void updateImage(const CvArr* arr); void startDisplayInfo(QString text, int delayms); void setOpenGlDrawCallback(CvOpenGlDrawCallback callback, void* userdata); void makeCurrentOpenGlContext(); void updateGl(); void setSize(QSize size_); protected: void initializeGL(); void resizeGL(int w, int h); void paintGL(); void mouseMoveEvent(QMouseEvent* event); void mousePressEvent(QMouseEvent* event); void mouseReleaseEvent(QMouseEvent* event); void mouseDoubleClickEvent(QMouseEvent* event); QSize sizeHint() const; private: QSize size; CvMouseCallback mouseCallback; void* mouseData; CvOpenGlDrawCallback glDrawCallback; void* glDrawData; void icvmouseHandler(QMouseEvent* event, type_mouse_event category, int& cv_event, int& flags); void icvmouseProcessing(QPointF pt, int cv_event, int flags); }; #endif // HAVE_QT_OPENGL class DefaultViewPort : public QGraphicsView, public ViewPort { Q_OBJECT public: DefaultViewPort(CvWindow* centralWidget, int arg2); ~DefaultViewPort(); QWidget* getWidget(); void setMouseCallBack(CvMouseCallback callback, void* param); void writeSettings(QSettings& settings); void readSettings(QSettings& settings); double getRatio(); void setRatio(int flags); void updateImage(const CvArr* arr); void startDisplayInfo(QString text, int delayms); void setOpenGlDrawCallback(CvOpenGlDrawCallback callback, void* userdata); void makeCurrentOpenGlContext(); void updateGl(); void setSize(QSize size_); public slots: //reference: //http://www.qtcentre.org/wiki/index.php?title=QGraphicsView:_Smooth_Panning_and_Zooming //http://doc.qt.nokia.com/4.6/gestures-imagegestures-imagewidget-cpp.html void siftWindowOnLeft(); void siftWindowOnRight(); void siftWindowOnUp() ; void siftWindowOnDown(); void resetZoom(); void imgRegion(); void ZoomIn(); void ZoomOut(); void saveView(); protected: void contextMenuEvent(QContextMenuEvent* event); void resizeEvent(QResizeEvent* event); void paintEvent(QPaintEvent* paintEventInfo); void wheelEvent(QWheelEvent* event); void mouseMoveEvent(QMouseEvent* event); void mousePressEvent(QMouseEvent* event); void mouseReleaseEvent(QMouseEvent* event); void mouseDoubleClickEvent(QMouseEvent* event); private: int param_keepRatio; //parameters (will be save/load) QTransform param_matrixWorld; CvMat* image2Draw_mat; QImage image2Draw_qt; int nbChannelOriginImage; //for mouse callback CvMouseCallback on_mouse; void* on_mouse_param; void scaleView(qreal scaleFactor, QPointF center); void moveView(QPointF delta); QPoint mouseCoordinate; QPointF positionGrabbing; QRect positionCorners; QTransform matrixWorld_inv; float ratioX, ratioY; bool isSameSize(IplImage* img1,IplImage* img2); QSize sizeHint() const; QPointer centralWidget; QPointer timerDisplay; bool drawInfo; QString infoText; QRectF target; void drawInstructions(QPainter *painter); void drawViewOverview(QPainter *painter); void drawImgRegion(QPainter *painter); void draw2D(QPainter *painter); void drawStatusBar(); void controlImagePosition(); void icvmouseHandler(QMouseEvent *event, type_mouse_event category, int &cv_event, int &flags); void icvmouseProcessing(QPointF pt, int cv_event, int flags); private slots: void stopDisplayInfo(); }; #endif