Image Component Library (ICL)
|
00001 /******************************************************************** 00002 ** Image Component Library (ICL) ** 00003 ** ** 00004 ** Copyright (C) 2006-2013 CITEC, University of Bielefeld ** 00005 ** Neuroinformatics Group ** 00006 ** Website: www.iclcv.org and ** 00007 ** http://opensource.cit-ec.de/projects/icl ** 00008 ** ** 00009 ** File : ICLQt/src/ICLQt/AbstractPlotWidget.h ** 00010 ** Module : ICLQt ** 00011 ** Authors: Christof Elbrechter ** 00012 ** ** 00013 ** ** 00014 ** GNU LESSER GENERAL PUBLIC LICENSE ** 00015 ** This file may be used under the terms of the GNU Lesser General ** 00016 ** Public License version 3.0 as published by the ** 00017 ** ** 00018 ** Free Software Foundation and appearing in the file LICENSE.LGPL ** 00019 ** included in the packaging of this file. Please review the ** 00020 ** following information to ensure the license requirements will ** 00021 ** be met: http://www.gnu.org/licenses/lgpl-3.0.txt ** 00022 ** ** 00023 ** The development of this software was supported by the ** 00024 ** Excellence Cluster EXC 277 Cognitive Interaction Technology. ** 00025 ** The Excellence Cluster EXC 277 is a grant of the Deutsche ** 00026 ** Forschungsgemeinschaft (DFG) in the context of the German ** 00027 ** Excellence Initiative. ** 00028 ** ** 00029 ********************************************************************/ 00030 00031 #pragma once 00032 00033 #include <ICLUtils/CompatMacros.h> 00034 #include <ICLUtils/Range.h> 00035 #include <ICLUtils/Rect32f.h> 00036 #include <ICLUtils/Configurable.h> 00037 #include <ICLMath/DynMatrix.h> 00038 #include <ICLQt/MouseEvent.h> 00039 #include <ICLQt/MouseHandler.h> 00040 00041 #include <ICLQt/ThreadedUpdatableWidget.h> 00042 00043 #include <QPen> 00044 #include <QBrush> 00045 #include <QPainter> 00046 00047 namespace icl{ 00048 namespace qt{ 00049 00050 00052 00086 class ICLQt_API AbstractPlotWidget : public ThreadedUpdatableWidget, public utils::Configurable{ 00087 struct Data; 00088 Data *data; 00089 00091 void property_changed(const Property &); 00092 00093 public: 00094 00095 00097 00103 void install(MouseHandler *h); 00104 00106 00107 void uninstall(MouseHandler *h); 00108 00110 enum PenType{ 00111 X_AXIS_PEN, 00112 Y_AXIS_PEN, 00113 X_TIC_PEN, 00114 Y_TIC_PEN, 00115 X_LABEL_PEN, 00116 Y_LABEL_PEN, 00117 X_GRID_PEN, 00118 Y_GRID_PEN, 00119 AXIS_NAME_PEN, 00120 NUM_PEN_TYPES 00121 }; 00122 00123 00125 AbstractPlotWidget(QWidget *parent=0); 00126 00128 ~AbstractPlotWidget(); 00129 00131 virtual void paintEvent(QPaintEvent *evt); 00132 00134 virtual void keyPressEvent(QKeyEvent *event); 00135 00137 void renderTo(QPainter &p); 00138 00140 void setBackground(const QBrush &bgBrush); 00141 00143 void setPen(PenType p, const QPen &pen); 00144 00146 00147 struct Pen{ 00149 00152 00171 Pen(const QPen &linePen=Qt::NoPen, 00172 const QPen &symbolPen=Qt::NoPen, 00173 char symbol= ' ', 00174 int symbolSize=5, 00175 const QBrush &fillBrush=Qt::NoBrush): 00176 linePen(linePen),symbolPen(symbolPen),symbol(symbol),symbolSize(symbolSize),fillBrush(fillBrush){} 00177 QPen linePen; 00178 QPen symbolPen; 00179 char symbol; 00180 int symbolSize; 00181 QBrush fillBrush; 00182 }; 00184 typedef utils::SmartPtr<Pen> PenPtr; 00185 00186 00188 00189 inline void render() { updateFromOtherThread(); } 00190 00192 00193 virtual utils::Rect32f getDataViewPort() const; 00194 00196 00204 void setDataViewPort(const utils::Rect32f &viewPort); 00205 00207 00210 void setDataViewPort(const utils::Range32f &xrange, const utils::Range32f &yrange); 00211 00213 void lock() const; 00214 00216 void unlock() const; 00217 00219 00250 void addAnnotations(const char type,const float *data, int num=1, 00251 const QPen &linePen = QColor(255,0,0), 00252 const QBrush &brush = Qt::NoBrush, 00253 const std::string &text="", const std::string &textDelim=","); 00254 00256 void clearAnnotations(); 00257 00259 00260 virtual void clear() { clearAnnotations(); } 00261 00263 typedef utils::Function<float,float,float> bgFunction; 00264 00266 00276 void setBackgroundFunction(bgFunction f); 00277 00279 00282 void updateBackgroundFunction(); 00283 00285 void removeBackgroundFunction(); 00286 00287 protected: 00288 00290 bool isZoomed() const; 00291 00293 virtual void mouseDoubleClickEvent(QMouseEvent *event); 00294 00296 virtual void mouseMoveEvent(QMouseEvent *event); 00297 00299 virtual void mousePressEvent(QMouseEvent *event); 00300 00302 virtual void mouseReleaseEvent(QMouseEvent *event); 00303 00305 virtual void enterEvent(QEvent *event); 00306 00308 virtual void leaveEvent(QEvent *event); 00309 00311 00312 virtual bool drawData(QPainter &p) = 0; 00313 00315 virtual void drawLegend(QPainter &p,const utils::Rect &where, bool horizontal); 00316 00317 00319 void drawDefaultLedgend(QPainter &p,const utils::Rect &where, bool horizontal, 00320 const std::vector<std::string> &rowNames, 00321 const std::vector<PenPtr> &pens); 00322 00324 00327 template<char s> static inline void draw_symbol(QPainter &p,int size, float x, float y){ 00328 ERROR_LOG("undefined given symbol ID"); 00329 } 00330 00332 float winToDrawX(int winX) const; 00333 00335 float winToDrawY(int winY) const; 00336 00338 utils::Point32f winToDraw(const utils::Point &p) const; 00339 00341 int drawToWinX(float drawX) const; 00342 00344 int drawToWinY(float drawY) const; 00345 00347 utils::Point drawToWin(const utils::Point32f &p) const; 00348 00350 utils::Rect32f getDynamicDataViewPort() const; 00351 00353 struct Locker{ 00354 const AbstractPlotWidget *w; 00355 00356 inline Locker(const AbstractPlotWidget *w):w(w){ this->w->lock(); } 00358 inline Locker(const AbstractPlotWidget &w):w(&w){ this->w->lock();} 00360 ~Locker() { w->unlock(); } 00361 }; 00362 }; 00363 00365 // (specialized) note, points have not size: use circle for larger round points ... 00366 template<> inline void AbstractPlotWidget::draw_symbol<'.'>(QPainter &p,int, float x, float y){ 00367 // p.drawPoint(QPoint(x,y)); 00368 p.drawLine(QPoint(x,y),QPoint(x,y)); 00369 } 00370 00371 template<> inline void AbstractPlotWidget::draw_symbol<'x'>(QPainter &p,int size, float x, float y){ 00372 p.drawLine(QPoint(x-size,y-size),QPoint(x+size,y+size)); 00373 p.drawLine(QPoint(x-size,y+size),QPoint(x+size,y-size)); 00374 } 00375 00376 template<> inline void AbstractPlotWidget::draw_symbol<'+'>(QPainter &p,int size, float x, float y){ 00377 p.drawLine(QPoint(x,y-size),QPoint(x,y+size)); 00378 p.drawLine(QPoint(x-size,y),QPoint(x+size,y)); 00379 } 00380 00381 template<> inline void AbstractPlotWidget::draw_symbol<'*'>(QPainter &p,int size, float x, float y){ 00382 draw_symbol<'+'>(p,(size*2)/3,x,y); 00383 draw_symbol<'x'>(p,size,x,y); 00384 } 00385 00387 template<> inline void AbstractPlotWidget::draw_symbol<'o'>(QPainter &p,int size, float x, float y){ 00388 p.drawEllipse(QRect(x-size,y-size,2*size,2*size)); 00389 } 00390 00391 template<> inline void AbstractPlotWidget::draw_symbol<'s'>(QPainter &p,int size, float x, float y){ 00392 p.drawRect(QRect(x-size,y-size,2*size,2*size)); 00393 } 00394 00395 template<> inline void AbstractPlotWidget::draw_symbol<'t'>(QPainter &p,int size, float x, float y){ 00396 const QPoint e[3] = { QPoint(x,y-size),QPoint(x+size,y+size),QPoint(x-size,y+size) }; 00397 p.drawConvexPolygon(e,3); 00398 } 00399 00400 template<> inline void AbstractPlotWidget::draw_symbol<'d'>(QPainter &p,int size, float x, float y){ 00401 const QPoint e[4] = { QPoint(x,y-size),QPoint(x+size,y),QPoint(x,y+size), QPoint(x-size,y) }; 00402 p.drawConvexPolygon(e,4); 00403 } 00405 } // namespace qt 00406 } 00407