Layer.h

Go to the documentation of this file.
00001 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
00002 
00003 /*
00004     Sonic Visualiser
00005     An audio file viewer and annotation editor.
00006     Centre for Digital Music, Queen Mary, University of London.
00007     This file copyright 2006 Chris Cannam and QMUL.
00008     
00009     This program is free software; you can redistribute it and/or
00010     modify it under the terms of the GNU General Public License as
00011     published by the Free Software Foundation; either version 2 of the
00012     License, or (at your option) any later version.  See the file
00013     COPYING included with this distribution for more information.
00014 */
00015 
00016 #ifndef _LAYER_H_
00017 #define _LAYER_H_
00018 
00019 #include "base/PropertyContainer.h"
00020 #include "base/XmlExportable.h"
00021 #include "base/Selection.h"
00022 
00023 #include <QObject>
00024 #include <QRect>
00025 #include <QXmlAttributes>
00026 #include <QMutex>
00027 #include <QPixmap>
00028 
00029 #include <map>
00030 #include <set>
00031 
00032 class ZoomConstraint;
00033 class Model;
00034 class QPainter;
00035 class View;
00036 class QMouseEvent;
00037 class Clipboard;
00038 class RangeMapper;
00039 
00046 class Layer : public PropertyContainer,
00047               public XmlExportable
00048 {
00049     Q_OBJECT
00050 
00051 public:
00052     Layer();
00053     virtual ~Layer();
00054 
00055     virtual const Model *getModel() const = 0;
00056     virtual Model *getModel() {
00057         return const_cast<Model *>(const_cast<const Layer *>(this)->getModel());
00058     }
00059 
00065     virtual const ZoomConstraint *getZoomConstraint() const { return 0; }
00066 
00075     virtual bool supportsOtherZoomLevels() const { return true; }
00076 
00077     virtual void paint(View *, QPainter &, QRect) const = 0;   
00078 
00079     enum VerticalPosition {
00080         PositionTop, PositionMiddle, PositionBottom
00081     };
00082     virtual VerticalPosition getPreferredTimeRulerPosition() const {
00083         return PositionMiddle;
00084     }
00085     virtual VerticalPosition getPreferredFrameCountPosition() const {
00086         return PositionBottom;
00087     }
00088     virtual bool hasLightBackground() const {
00089         return true;
00090     }
00091 
00092     virtual QString getPropertyContainerIconName() const;
00093 
00094     virtual QString getPropertyContainerName() const {
00095         if (m_presentationName != "") return m_presentationName;
00096         else return objectName();
00097     }
00098 
00099     virtual void setPresentationName(QString name);
00100 
00101     virtual QString getLayerPresentationName() const;
00102     virtual QPixmap getLayerPresentationPixmap(QSize) const { return QPixmap(); }
00103 
00104     virtual int getVerticalScaleWidth(View *, QPainter &) const { return 0; }
00105     virtual void paintVerticalScale(View *, QPainter &, QRect) const { }
00106 
00107     virtual bool getCrosshairExtents(View *, QPainter &, QPoint /* cursorPos */,
00108                                      std::vector<QRect> &) const {
00109         return false;
00110     }
00111     virtual void paintCrosshairs(View *, QPainter &, QPoint) const { }
00112 
00113     virtual void paintMeasurementRects(View *, QPainter &,
00114                                        bool showFocus, QPoint focusPoint) const;
00115 
00116     virtual bool nearestMeasurementRectChanged(View *, QPoint prev,
00117                                                QPoint now) const;
00118 
00119     virtual QString getFeatureDescription(View *, QPoint &) const {
00120         return "";
00121     }
00122 
00123     enum SnapType {
00124         SnapLeft,
00125         SnapRight,
00126         SnapNearest,
00127         SnapNeighbouring
00128     };
00129 
00149     virtual bool snapToFeatureFrame(View *   /* v */,
00150                                     int &    /* frame */,
00151                                     size_t &resolution,
00152                                     SnapType /* snap */) const {
00153         resolution = 1;
00154         return false;
00155     }
00156 
00157     // Draw, erase, and edit modes:
00158     //
00159     // Layer needs to get actual mouse events, I guess.  Draw mode is
00160     // probably the easier.
00161 
00162     virtual void drawStart(View *, QMouseEvent *) { }
00163     virtual void drawDrag(View *, QMouseEvent *) { }
00164     virtual void drawEnd(View *, QMouseEvent *) { }
00165 
00166     virtual void eraseStart(View *, QMouseEvent *) { }
00167     virtual void eraseDrag(View *, QMouseEvent *) { }
00168     virtual void eraseEnd(View *, QMouseEvent *) { }
00169 
00170     virtual void editStart(View *, QMouseEvent *) { }
00171     virtual void editDrag(View *, QMouseEvent *) { }
00172     virtual void editEnd(View *, QMouseEvent *) { }
00173 
00174     // Measurement rectangle (or equivalent).  Unlike draw and edit,
00175     // the base Layer class can provide working implementations of
00176     // these for most situations.
00177     //
00178     virtual void measureStart(View *, QMouseEvent *);
00179     virtual void measureDrag(View *, QMouseEvent *);
00180     virtual void measureEnd(View *, QMouseEvent *);
00181     virtual void measureDoubleClick(View *, QMouseEvent *);
00182 
00183     virtual bool haveCurrentMeasureRect() const {
00184         return m_haveCurrentMeasureRect;
00185     }
00186     virtual void deleteCurrentMeasureRect(); // using a command
00187 
00193     virtual bool editOpen(View *, QMouseEvent *) { return false; }
00194 
00195     virtual void moveSelection(Selection, size_t /* newStartFrame */) { }
00196     virtual void resizeSelection(Selection, Selection /* newSize */) { }
00197     virtual void deleteSelection(Selection) { }
00198 
00199     virtual void copy(View *, Selection, Clipboard & /* to */) { }
00200 
00208     virtual bool paste(View *,
00209                        const Clipboard & /* from */,
00210                        int /* frameOffset */,
00211                        bool /* interactive */) { return false; }
00212 
00213     // Text mode:
00214     //
00215     // Label nearest feature.  We need to get the feature coordinates
00216     // and current label from the layer, and then the pane can pop up
00217     // a little text entry dialog at the right location.  Or we edit
00218     // in place?  Probably the dialog is easier.
00219 
00230     virtual bool isLayerScrollable(const View *) const { return true; }
00231 
00240     virtual bool isLayerOpaque() const { return false; }
00241 
00242     enum ColourSignificance {
00243         ColourAbsent,
00244         ColourIrrelevant,
00245         ColourDistinguishes,
00246         ColourAndBackgroundSignificant,
00247         ColourHasMeaningfulValue
00248     };
00249 
00268     virtual ColourSignificance getLayerColourSignificance() const = 0;
00269 
00276     virtual bool isLayerEditable() const { return false; }
00277 
00285     virtual int getCompletion(View *) const { return 100; }
00286 
00287     virtual void setObjectName(const QString &name);
00288 
00296     virtual void toXml(QTextStream &stream, QString indent = "",
00297                        QString extraAttributes = "") const;
00298 
00304     virtual void setProperties(const QXmlAttributes &) = 0;
00305 
00312     virtual void toBriefXml(QTextStream &stream,
00313                             QString indent = "",
00314                             QString extraAttributes = "") const;
00315 
00321     virtual void addMeasurementRect(const QXmlAttributes &);
00322 
00334     virtual void setLayerDormant(const View *v, bool dormant);
00335 
00340     virtual bool isLayerDormant(const View *v) const;
00341 
00342     virtual PlayParameters *getPlayParameters();
00343 
00344     virtual bool needsTextLabelHeight() const { return false; }
00345 
00346     virtual bool hasTimeXAxis() const { return true; }
00347 
00357     virtual bool getValueExtents(float &min, float &max,
00358                                  bool &logarithmic, QString &unit) const = 0;
00359 
00368     virtual bool getDisplayExtents(float & /* min */,
00369                                    float & /* max */) const {
00370         return false;
00371     }
00372 
00380     virtual bool setDisplayExtents(float /* min */,
00381                                    float /* max */) {
00382         return false;
00383     }
00384 
00391     virtual bool getXScaleValue(const View *v, int x,
00392                                 float &value, QString &unit) const;
00393 
00398     virtual bool getYScaleValue(const View *, int /* y */,
00399                                 float &/* value */, QString &/* unit */) const {
00400         return false;
00401     }
00402 
00409     virtual bool getYScaleDifference(const View *v, int y0, int y1,
00410                                      float &diff, QString &unit) const;
00411         
00426     virtual int getVerticalZoomSteps(int & /* defaultStep */) const { return 0; }
00427 
00434     virtual int getCurrentVerticalZoomStep() const { return 0; }
00435 
00442     virtual void setVerticalZoomStep(int) { }
00443 
00450     virtual RangeMapper *getNewVerticalZoomRangeMapper() const { return 0; }
00451 
00452 public slots:
00453     void showLayer(View *, bool show);
00454 
00455 signals:
00456     void modelChanged();
00457     void modelCompletionChanged();
00458     void modelAlignmentCompletionChanged();
00459     void modelChanged(size_t startFrame, size_t endFrame);
00460     void modelReplaced();
00461 
00462     void layerParametersChanged();
00463     void layerParameterRangesChanged();
00464     void layerMeasurementRectsChanged();
00465     void layerNameChanged();
00466 
00467     void verticalZoomChanged();
00468 
00469 protected:
00470     void connectSignals(const Model *);
00471 
00472     virtual size_t alignToReference(View *v, size_t frame) const;
00473     virtual size_t alignFromReference(View *v, size_t frame) const;
00474     bool clipboardHasDifferentAlignment(View *v, const Clipboard &clip) const;
00475 
00476     struct MeasureRect {
00477 
00478         mutable QRect pixrect;
00479         bool haveFrames;
00480         long startFrame; // only valid if haveFrames
00481         long endFrame;   // ditto
00482         double startY;
00483         double endY;
00484 
00485         bool operator<(const MeasureRect &mr) const;
00486         void toXml(QTextStream &stream, QString indent) const;
00487     };
00488 
00489     class AddMeasurementRectCommand : public Command
00490     {
00491     public:
00492         AddMeasurementRectCommand(Layer *layer, MeasureRect rect) :
00493             m_layer(layer), m_rect(rect) { }
00494 
00495         virtual QString getName() const;
00496         virtual void execute();
00497         virtual void unexecute();
00498 
00499     private:
00500         Layer *m_layer;
00501         MeasureRect m_rect;
00502     };
00503 
00504     class DeleteMeasurementRectCommand : public Command
00505     {
00506     public:
00507         DeleteMeasurementRectCommand(Layer *layer, MeasureRect rect) :
00508             m_layer(layer), m_rect(rect) { }
00509 
00510         virtual QString getName() const;
00511         virtual void execute();
00512         virtual void unexecute();
00513 
00514     private:
00515         Layer *m_layer;
00516         MeasureRect m_rect;
00517     };
00518 
00519     void addMeasureRectToSet(const MeasureRect &r) {
00520         m_measureRects.insert(r);
00521         emit layerMeasurementRectsChanged();
00522     }
00523 
00524     void deleteMeasureRectFromSet(const MeasureRect &r) {
00525         m_measureRects.erase(r); 
00526         emit layerMeasurementRectsChanged();
00527     }
00528 
00529     typedef std::set<MeasureRect> MeasureRectSet;
00530     MeasureRectSet m_measureRects;
00531     MeasureRect m_draggingRect;
00532     bool m_haveDraggingRect;
00533     mutable bool m_haveCurrentMeasureRect;
00534     mutable QPoint m_currentMeasureRectPoint;
00535    
00536     // Note that pixrects are only correct for a single view.
00537     // So we should update them at the start of the paint procedure
00538     // (painting is single threaded) and only use them after that.
00539     void updateMeasurePixrects(View *v) const;
00540 
00541     virtual void updateMeasureRectYCoords(View *v, const MeasureRect &r) const;
00542     virtual void setMeasureRectYCoord(View *v, MeasureRect &r, bool start, int y) const;
00543     virtual void setMeasureRectFromPixrect(View *v, MeasureRect &r, QRect pixrect) const;
00544 
00545     // This assumes updateMeasurementPixrects has been called
00546     MeasureRectSet::const_iterator findFocusedMeasureRect(QPoint) const;
00547 
00548     void paintMeasurementRect(View *v, QPainter &paint,
00549                               const MeasureRect &r, bool focus) const;
00550 
00551     QString m_presentationName;
00552 
00553 private:
00554     mutable QMutex m_dormancyMutex;
00555     mutable std::map<const void *, bool> m_dormancy;
00556 };
00557 
00558 #endif
00559 

Generated on Wed Feb 20 15:45:26 2008 for SonicVisualiser by  doxygen 1.5.1