casa
$Rev:20696$
|
00001 //# Copyright (C) 2005 00002 //# Associated Universities, Inc. Washington DC, USA. 00003 //# 00004 //# This library is free software; you can redistribute it and/or modify it 00005 //# under the terms of the GNU Library General Public License as published by 00006 //# the Free Software Foundation; either version 2 of the License, or (at your 00007 //# option) any later version. 00008 //# 00009 //# This library is distributed in the hope that it will be useful, but WITHOUT 00010 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00011 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 00012 //# License for more details. 00013 //# 00014 //# You should have received a copy of the GNU Library General Public License 00015 //# along with this library; if not, write to the Free Software Foundation, 00016 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 00017 //# 00018 //# Correspondence concerning AIPS++ should be addressed as follows: 00019 //# Internet email: aips2-request@nrao.edu. 00020 //# Postal address: AIPS++ Project Office 00021 //# National Radio Astronomy Observatory 00022 //# 520 Edgemont Road 00023 //# Charlottesville, VA 22903-2475 USA 00024 //# 00025 00026 #ifndef QTCANVAS_H 00027 #define QTCANVAS_H 00028 00029 #include <casa/aips.h> 00030 #include <casa/BasicSL/String.h> 00031 #include <casa/Containers/Record.h> 00032 #include <casa/Arrays/Array.h> 00033 #include <casa/Arrays/ArrayMath.h> 00034 #include <casa/Arrays/Vector.h> 00035 #include <casa/Arrays/Matrix.h> 00036 #include <casa/Inputs/Input.h> 00037 #include <casa/Arrays/IPosition.h> 00038 00039 #include <display/QtPlotter/QtPlotSettings.h> 00040 #include <display/QtPlotter/CanvasCurve.h> 00041 #include <display/QtPlotter/WorldCanvasTranslator.h> 00042 #include <display/QtPlotter/ProfileFitMarker.h> 00043 #include <display/QtPlotter/MolecularLine.h> 00044 #include <display/QtPlotter/canvasMode/CanvasMode.h> 00045 00046 #include <graphics/X11/X_enter.h> 00047 #include <QDir> 00048 #include <QColor> 00049 #include <QHash> 00050 #include <QWidget> 00051 #include <QMouseEvent> 00052 #include <QToolButton> 00053 #include <QDialog> 00054 #include <QPixmap> 00055 #include <QVBoxLayout> 00056 #include <QPainterPath> 00057 #include <QLabel> 00058 #include <QMenu> 00059 #include <map> 00060 #include <vector> 00061 #include <graphics/X11/X_exit.h> 00062 00063 namespace casa { 00064 00065 class Annotation; 00066 00067 #define QT_DIAMOND_SIZE 5 00068 00069 class GraphLabel{ 00070 public: 00071 QString text; 00072 QString fontName; 00073 int fontSize; 00074 QColor color; 00075 GraphLabel() : text(""), fontName(""), fontSize(12), color(Qt::blue) {} 00076 }; 00077 00078 class QtCanvas : public QWidget, public WorldCanvasTranslator 00079 { 00080 Q_OBJECT 00081 00082 friend class CanvasModeAnnotation; 00083 friend class CanvasModeRangeSelection; 00084 friend class CanvasModeChannel; 00085 friend class CanvasModeContextMenu; 00086 friend class CanvasModeZoom; 00087 00088 public: 00089 QtCanvas(QWidget *parent = 0); 00090 00091 void setPlotSettings(const QtPlotSettings &settings); 00092 void setTopAxisRange(const Vector<Float> &xValues, bool topAxisDescending ); 00093 void setFrameMarker( float framePositionX ); 00094 void setZoomRectColor( QColor color ); 00095 //Returns the spectrum as it is currently displayed in the canvas (with 00096 //possible zooming). 00097 void getCanvasDomain( double* minValue, double* maxValue, QString& units); 00098 00099 CurveData getCurveData(int); 00100 ErrorData getCurveError(int id); 00101 QString getCurveName(int id); 00102 void setCurveName(int id, const QString& name ); 00103 void curveColorsChanged(); 00104 QColor getCurveColor( int id ); 00105 CanvasCurve getCurve( const QString& curveName ); 00106 int getLineCount(); 00107 void curveLabelsChanged(); 00108 void clearCurve(); 00109 void clearFitCurves(); 00110 void clearMolecularLines( bool refresh = true ); 00111 void setDataRange(); 00112 void setImageMode(bool); 00113 QPixmap* graph(); 00114 void drawBackBuffer(QPainter *); 00115 //Draws a vertical line indicating the current frame. 00116 void drawFrameMarker( QPainter* ); 00117 QString getUnits( QtPlotSettings::AxisIndex axisIndex = QtPlotSettings::xBottom ); 00118 QList<MolecularLine*> getMolecularLines() const; 00119 00120 //Plotting curves 00121 void plotPolyLines(QString); 00122 template<class T> void plotPolyLine(const Vector<T>&, const Vector<T>&); 00123 void plotPolyLine(const Vector<Float> &x, const Vector<Float> &y, const Vector<Float> &e, 00124 const QString& lb=""); 00125 enum ColorCategory { TITLE_COLOR, CURVE_COLOR, CURVE_COLOR_PRIMARY, 00126 CURVE_COLOR_SECONDARY, WARNING_COLOR, CURVE_TRADITIONAL }; 00127 void addPolyLine(const Vector<Float> &x, const Vector<Float> &y, 00128 const QString& lb="", ColorCategory colorCategory=CURVE_COLOR ); 00129 void addMolecularLine(MolecularLine* molecularLine ); 00130 QList<QString> getMolecularLineNames() const; 00131 00132 template<class T> void plotPolyLine(const Matrix<T> &verts); 00133 00134 QSize minimumSizeHint() const; 00135 QSize sizeHint() const; 00136 ~QtCanvas(); 00137 00138 00139 void setTitle(const QString &text, int fontSize = 13,const QString &font = FONT_NAME); 00140 QString getTitle(){return title.text;}; 00141 00142 bool isShowChannelLine(); 00143 void setShowChannelLine( bool showLine ); 00144 void setChannelLineColor( QColor color ); 00145 00146 void setXLabel(const QString &text, int fontSize = 10, 00147 const QString &font = FONT_NAME, QtPlotSettings::AxisIndex axisIndex=QtPlotSettings::xBottom); 00148 void setWelcome(const QString &text, int fontSize = 14, 00149 const QString &font = FONT_NAME); 00150 void setAutoScaleX(bool autoScale); 00151 void setAutoScaleY(bool autoScale); 00152 void setShowGrid(int a) {showGrid = a; refreshPixmap();} 00153 bool getAutoScaleX( ) {return autoScaleX;} 00154 bool getAutoScaleY( ) {return autoScaleY;} 00155 int getShowGrid( ) {return showGrid;} 00156 void setPlotError(int a) {plotError = a; setDataRange();} 00157 00158 //Whether or not to show a top axis on the plot. 00159 void setShowTopAxis( bool showAxis ); 00160 bool getShowTopAxis() const { return showTopAxis; } 00161 00162 //Whether or not to show tool tips with the x,y coordinates 00163 //of the points on the plot. 00164 void setShowToolTips( bool toolTipsVisible ){ showToolTips = toolTipsVisible; } 00165 bool getShowToolTips() const { return showToolTips; } 00166 00167 //Sets the coordinates for the x and y points that are displayed 00168 //as tooltips. 00169 void setToolTipXUnit( const QString& xUnit ){ toolTipXUnit = xUnit; } 00170 00171 //Stores the location of a (center,peak) point that represents an initial 00172 //Gaussian estimate for spectral line fitting. 00173 void setProfileFitMarkerCenterPeak( int index, double center, double peak); 00174 00175 //Stores the fwhm and the y value of the fwhm for an initial Gaussian estimate 00176 //for spectral line fitting. 00177 void setProfileFitMarkerFWHM( int index, double fwhm, double fwhmHeight); 00178 00179 //Whether or not to plot a line graph or instead plot the points as a 00180 //step function. 00181 bool isDisplayStepFunction() const; 00182 void setDisplayStepFunction( bool displayAsStepFunction ); 00183 00184 //Used for customizing the curve colors on the canvas. 00185 void setTraditionalCurveColors( const QList<QString>& colors ); 00186 void setMainCurveColors( const QList<QString>& colors ); 00187 void setFitCurveColors( const QList<QString>& colors ); 00188 void setSummaryCurveColors( const QList<QString>& colors ); 00189 00190 //If this flag is set, only 'traditional' colors will be used. 00191 void setTraditionalColors( bool traditionalColors ); 00192 static const QString FONT_NAME; 00193 00194 //Customization of the curve legend. 00195 void setShowLegend( bool visible ); 00196 bool isShowLegend() const; 00197 void setLegendPosition( int position ); 00198 int getLegendPosition() const; 00199 00200 //Set the yaxis units the image is using ( units the data we are getting is in). 00201 void setImageYUnits( const QString& imageUnits ); 00202 00203 00204 enum TaskMode {/*UNKNOWN_MODE,*/ SPECTRAL_LINE_MODE, LINE_OVERLAY_MODE, MODE_COUNT }; 00205 00206 00207 //Units we will be displaying the y-axis in which may be different 00208 //from the intrinsic image units. 00209 QString getDisplayYUnits(); 00210 void setDisplayYUnits( const QString& displayUnits ); 00211 00212 int getCurZoom(); 00213 int getZoomStackSize(); 00214 00215 public slots: 00216 void zoomIn(); 00217 void zoomOut(); 00218 void zoomNeutral(); 00219 void changeTaskMode( int mode ); 00220 void createAnnotationText(); 00221 void rangeSelectionMode(); 00222 void channelPositioningMode(); 00223 00224 signals: 00225 void xRangeChanged(double xmin, double xmax); 00226 void channelSelect(float xvalue); 00227 void specFitEstimateSpecified( double xValue, double yValue, bool centerPeak ); 00228 void findRedshiftAt( double center, double peak ); 00229 void channelRangeSelect( float startVal, float endVal ); 00230 void curvesChanged(); 00231 void clearPaletteModes(); 00232 void togglePalette( int modeIndex ); 00233 00234 protected: 00235 void paintEvent(QPaintEvent *event); 00236 void resizeEvent(QResizeEvent *event); 00237 void mousePressEvent(QMouseEvent *event); 00238 void mouseMoveEvent(QMouseEvent *event); 00239 void mouseReleaseEvent(QMouseEvent *event); 00240 void keyPressEvent(QKeyEvent *event); 00241 void keyReleaseEvent(QKeyEvent *event); 00242 void wheelEvent(QWheelEvent *event); 00243 00244 void updateRubberBandRegion(); 00245 void updatexRangeBandRegion(); 00246 void drawGrid(QPainter *painter); 00247 void drawTicks(QPainter *painter); 00248 void drawLabels(QPainter *painter); 00249 void drawWelcome(QPainter *painter); 00250 void drawCurves(QPainter *painter); 00251 void drawxRange(QPainter *painter); 00252 00253 00254 private slots: 00255 void deleteSelectedAnnotation(); 00256 void editSelectedAnnotation(); 00257 void gaussianCenterPeakSelected(); 00258 void gaussianFWHMSelected(); 00259 void findRedshift(); 00260 00261 private: 00262 00263 //Zoom functionality 00264 void zoomYBasedOnX( QtPlotSettings& settings, double zoomFactor, bool zoomIn ); 00265 pair<double,double> getRangeFor( double zoomFactor, bool zoomIn, double minX, double maxX ); 00266 void increaseCurZoom(); 00267 void defaultZoomIn(); 00268 void defaultZoomOut(); 00269 00279 void setCurveData(int id, const CurveData &data, const ErrorData &error=ErrorData(), 00280 const QString& lb="", ColorCategory colorCategory = CURVE_COLOR); 00281 void refreshPixmap(); 00282 00287 void displayToolTip( QMouseEvent* event ) const; 00288 00293 void adjustExtremes( double* const min, double* const max ) const; 00294 00300 double getDataY( int pixelPosition ) const; 00301 00307 double getDataX( int pixelPosition ) const; 00308 00309 //WorldCanvasTranslator interface methods. 00315 int getPixelX( double dataX ) const; 00316 00322 int getPixelY ( double dataY ) const; 00323 00334 QString findCoords( double x, double y ) const; 00335 00339 int getRectHeight() const; 00340 00344 int getRectWidth() const; 00345 00349 int getRectBottom() const; 00350 00354 int getRectLeft() const; 00355 00364 QString getXTickLabel( int index, int tickCount, QtPlotSettings::AxisIndex axisIndex ) const; 00365 00371 void initContextMenu(); 00372 void addDiamond( int x, int y, int diamondSize, QPainterPath& points ) const; 00373 bool storeClickPosition( QMouseEvent* event ); 00374 int getLastAxis() const; 00375 void stripCurveTitleNumbers( QString& curveName ) const; 00376 bool duplicateCurve( QString& targetLabel ); 00377 void setYLabel(const QString &text, int fontSize = 10, const QString &font = FONT_NAME); 00378 00379 //Annotation methods 00380 void selectAnnotation( QMouseEvent* event, bool select = true ); 00381 bool isAnnotation( QMouseEvent* event ) const; 00382 Annotation* getSelectedAnnotation() const; 00383 00384 //Mouse Events 00385 void storeActiveAnnotation( QMouseEvent* event ); 00386 void selectChannel( QMouseEvent* event ); 00387 void updateChannel( QMouseEvent* event ); 00388 void moveChannel( QMouseEvent* event ); 00389 void startRangeX( QMouseEvent* event ); 00390 void updateRangeX( QMouseEvent* event ); 00391 void endRangeX( QMouseEvent* event ); 00392 void startZoomRect( QMouseEvent* event ); 00393 void updateZoomRect( QMouseEvent* event ); 00394 void endZoomRect( QMouseEvent* event ); 00395 void resetSelectedAnnotation( QMouseEvent* event ); 00396 void drawMolecularLines( QPainter& painter ); 00397 00398 //Plot Margins 00399 const int MARGIN_LEFT; 00400 const int MARGIN_BOTTOM; 00401 const int MARGIN_TOP; 00402 const int MARGIN_RIGHT; 00403 const int FRACZOOM; 00404 const double ZERO_LIMIT; 00405 00406 GraphLabel title; 00407 GraphLabel xLabel[2]; 00408 GraphLabel yLabel; 00409 GraphLabel welcome; 00410 00411 std::map<int, CanvasCurve> curveMap; 00412 std::vector<QtPlotSettings> zoomStack; 00413 QList<MolecularLine*> molecularLineStack; 00414 std::pair<double,double> topAxisRange; 00415 00416 int curZoom; 00417 int curMarker; 00418 bool rubberBandIsShown; 00419 bool xRangeIsShown; 00420 bool imageMode; 00421 bool xRangeMode; 00422 double xRangeStart; 00423 double xRangeEnd; 00424 QRect rubberBandRect; 00425 QRect xRangeRect; 00426 QPixmap pixmap; 00427 QPixmap backBuffer; 00428 Matrix<uInt> *pMask; 00429 00430 QPoint currentCursorPosition; 00431 QColor xcursor; 00432 00433 bool autoScaleX; 00434 bool autoScaleY; 00435 int plotError; 00436 int showGrid; 00437 00438 int xRectStart; 00439 int xRectEnd; 00440 00441 bool showTopAxis; 00442 bool showToolTips; 00443 bool showFrameMarker; 00444 bool displayStepFunction; 00445 QString toolTipXUnit; 00446 QString yUnitImage; 00447 QString yUnitDisplay; 00448 00449 //Context Menu 00450 QMenu contextMenu; 00451 QAction* centerPeakAction; 00452 QAction* fwhmAction; 00453 QAction* findRedshiftAction; 00454 QAction* createAnnotationAction; 00455 QAction* editAnnotationAction; 00456 QAction* deleteAnnotationAction; 00457 void showContextMenu( QMouseEvent* event ); 00458 00459 //Profile Fitting Gaussian Estimation 00460 double gaussianEstimateX; 00461 double gaussianEstimateY; 00462 QList<ProfileFitMarker> profileFitMarkers; 00463 00464 ProfileFitMarker getMarker( int index ) const; 00465 void setMarker( int index, ProfileFitMarker& marker ); 00466 00467 00475 QColor getDiscreteColor(ColorCategory colorCategory, int id=0); 00476 QColor frameMarkerColor; 00477 QColor zoomColor; 00478 QList<QString> mainCurveColorList; 00479 QList<QString> fitCurveColorList; 00480 QList<QString> fitSummaryCurveColorList; 00481 QList<QString> traditionalCurveColorList; 00482 00483 int curveCount; 00484 int curveCountPrimary; 00485 int curveCountSecondary; 00486 00487 //The optical spectral line fitting curve needs to use 00488 //the traditional color list rather than a customizable one. 00489 //That is the purpose of this flag. 00490 bool traditionalColors; 00491 00492 //Whether the pixel canvas should show a legend with the curves. 00493 bool showLegend; 00494 00495 //Where the curve legend should appear relative to this 00496 //canvas. 00497 int legendPosition; 00498 00499 //The x location for the vertical line representing the 00500 //current frame position. 00501 float framePositionX; 00502 00503 //Indicates the current work focus of the profiler 00504 TaskMode taskMode; 00505 00506 float channelSelectValue; 00507 00508 Annotation* selectedAnnotation; 00509 vector<Annotation*> annotations; 00510 00511 //Returns true if the user is in the process of drawing an 00512 //annotation. 00513 bool isAnnotationActive() const; 00514 00515 Annotation* getActiveAnnotation() const; 00516 CanvasMode* currentMode; 00517 }; 00518 00519 } 00520 #endif 00521