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: ~ViewPort()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