svgui  1.9
View.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.
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 _VIEW_H_
00017 #define _VIEW_H_
00018 
00019 #include <QFrame>
00020 #include <QProgressBar>
00021 
00022 #include "base/ZoomConstraint.h"
00023 #include "base/PropertyContainer.h"
00024 #include "ViewManager.h"
00025 #include "base/XmlExportable.h"
00026 
00027 // #define DEBUG_VIEW_WIDGET_PAINT 1
00028 
00029 class Layer;
00030 class ViewPropertyContainer;
00031 
00032 class QPushButton;
00033 
00034 #include <map>
00035 #include <set>
00036 
00050 class View : public QFrame,
00051              public XmlExportable
00052 {
00053     Q_OBJECT
00054 
00055 public:
00060     virtual ~View();
00061 
00067     int getStartFrame() const;
00068 
00073     void setStartFrame(int);
00074 
00081     int getCentreFrame() const { return m_centreFrame; }
00082 
00086     void setCentreFrame(int f) { setCentreFrame(f, true); }
00087 
00093     int getEndFrame() const;
00094 
00099     int getXForFrame(int frame) const;
00100 
00104     int getFrameForX(int x) const;
00105 
00114     float getYForFrequency(float frequency, float minFreq, float maxFreq, 
00115                            bool logarithmic) const;
00116 
00123     float getFrequencyForY(int y, float minFreq, float maxFreq,
00124                            bool logarithmic) const;
00125 
00129     int getZoomLevel() const;
00130 
00136     virtual void setZoomLevel(int z);
00137 
00141     virtual void zoom(bool in);
00142 
00146     virtual void scroll(bool right, bool lots, bool doEmit = true);
00147 
00153     virtual void addLayer(Layer *v);
00154 
00160     virtual void removeLayer(Layer *v);
00161 
00166     virtual int getLayerCount() const { return m_layerStack.size(); }
00167 
00174     virtual Layer *getLayer(int n) {
00175         if (n < int(m_layerStack.size())) return m_layerStack[n];
00176         else return 0;
00177     }
00178 
00186     virtual Layer *getFixedOrderLayer(int n) {
00187         if (n < int(m_fixedOrderLayers.size())) return m_fixedOrderLayers[n];
00188         else return 0;
00189     }
00190 
00196     virtual Layer *getInteractionLayer();
00197 
00198     virtual const Layer *getInteractionLayer() const;
00199 
00214     virtual Layer *getSelectedLayer();
00215 
00216     virtual const Layer *getSelectedLayer() const;
00217 
00227     virtual Layer *getTopLayer() {
00228         return m_layerStack.empty() ? 0 : m_layerStack[m_layerStack.size()-1];
00229     }
00230 
00231     virtual void setViewManager(ViewManager *m);
00232     virtual void setViewManager(ViewManager *m, int initialFrame);
00233     virtual ViewManager *getViewManager() const { return m_manager; }
00234 
00235     virtual void setFollowGlobalPan(bool f);
00236     virtual bool getFollowGlobalPan() const { return m_followPan; }
00237 
00238     virtual void setFollowGlobalZoom(bool f);
00239     virtual bool getFollowGlobalZoom() const { return m_followZoom; }
00240 
00241     virtual bool hasLightBackground() const;
00242     virtual QColor getForeground() const;
00243     virtual QColor getBackground() const;
00244 
00245     enum TextStyle {
00246         BoxedText,
00247         OutlinedText,
00248         OutlinedItalicText
00249     };
00250 
00251     virtual void drawVisibleText(QPainter &p, int x, int y,
00252                                  QString text, TextStyle style) const;
00253 
00254     virtual void drawMeasurementRect(QPainter &p, const Layer *,
00255                                      QRect rect, bool focus) const;
00256 
00257     virtual bool shouldShowFeatureLabels() const {
00258         return m_manager && m_manager->shouldShowFeatureLabels();
00259     }
00260     virtual bool shouldIlluminateLocalFeatures(const Layer *, QPoint &) const {
00261         return false;
00262     }
00263     virtual bool shouldIlluminateLocalSelection(QPoint &, bool &, bool &) const {
00264         return false;
00265     }
00266 
00267     virtual void setPlaybackFollow(PlaybackFollowMode m);
00268     virtual PlaybackFollowMode getPlaybackFollow() const { return m_followPlay; }
00269 
00270     typedef PropertyContainer::PropertyName PropertyName;
00271 
00272     // We implement the PropertyContainer API, although we don't
00273     // actually subclass PropertyContainer.  We have our own
00274     // PropertyContainer that we can return on request that just
00275     // delegates back to us.
00276     virtual PropertyContainer::PropertyList getProperties() const;
00277     virtual QString getPropertyLabel(const PropertyName &) const;
00278     virtual PropertyContainer::PropertyType getPropertyType(const PropertyName &) const;
00279     virtual int getPropertyRangeAndValue(const PropertyName &,
00280                                          int *min, int *max, int *deflt) const;
00281     virtual QString getPropertyValueLabel(const PropertyName &,
00282                                           int value) const;
00283     virtual void setProperty(const PropertyName &, int value);
00284     virtual QString getPropertyContainerName() const {
00285         return objectName();
00286     }
00287     virtual QString getPropertyContainerIconName() const = 0;
00288 
00289     virtual int getPropertyContainerCount() const;
00290 
00291     // The 0th property container is the view's own; the rest are the
00292     // layers in fixed-order series
00293     virtual const PropertyContainer *getPropertyContainer(int i) const;
00294     virtual PropertyContainer *getPropertyContainer(int i);
00295 
00296     // Render the contents on a wide canvas
00297     virtual QImage *toNewImage(int f0, int f1);
00298     virtual QImage *toNewImage();
00299     virtual QSize getImageSize(int f0, int f1);
00300     virtual QSize getImageSize();
00301 
00302     virtual int getTextLabelHeight(const Layer *layer, QPainter &) const;
00303 
00304     virtual bool getValueExtents(QString unit, float &min, float &max,
00305                                  bool &log) const;
00306 
00307     virtual void toXml(QTextStream &stream, QString indent = "",
00308                        QString extraAttributes = "") const;
00309 
00310     // First frame actually in model, to right of scale, if present
00311     virtual int getFirstVisibleFrame() const;
00312     virtual int getLastVisibleFrame() const;
00313 
00314     int getModelsStartFrame() const;
00315     int getModelsEndFrame() const;
00316 
00317     typedef std::set<Model *> ModelSet;
00318     ModelSet getModels();
00319 
00321     Model *getAligningModel() const;
00322     int alignFromReference(int) const;
00323     int alignToReference(int) const;
00324     int getAlignedPlaybackFrame() const;
00325 
00326 signals:
00327     void propertyContainerAdded(PropertyContainer *pc);
00328     void propertyContainerRemoved(PropertyContainer *pc);
00329     void propertyContainerPropertyChanged(PropertyContainer *pc);
00330     void propertyContainerPropertyRangeChanged(PropertyContainer *pc);
00331     void propertyContainerNameChanged(PropertyContainer *pc);
00332     void propertyContainerSelected(PropertyContainer *pc);
00333     void propertyChanged(PropertyContainer::PropertyName);
00334 
00335     void layerModelChanged();
00336 
00337     void centreFrameChanged(int frame,
00338                             bool globalScroll,
00339                             PlaybackFollowMode followMode);
00340 
00341     void zoomLevelChanged(int, bool);
00342 
00343     void contextHelpChanged(const QString &);
00344 
00345 public slots:
00346     virtual void modelChanged();
00347     virtual void modelChangedWithin(int startFrame, int endFrame);
00348     virtual void modelCompletionChanged();
00349     virtual void modelAlignmentCompletionChanged();
00350     virtual void modelReplaced();
00351     virtual void layerParametersChanged();
00352     virtual void layerParameterRangesChanged();
00353     virtual void layerMeasurementRectsChanged();
00354     virtual void layerNameChanged();
00355 
00356     virtual void globalCentreFrameChanged(int);
00357     virtual void viewCentreFrameChanged(View *, int);
00358     virtual void viewManagerPlaybackFrameChanged(int);
00359     virtual void viewZoomLevelChanged(View *, int, bool);
00360 
00361     virtual void propertyContainerSelected(View *, PropertyContainer *pc);
00362 
00363     virtual void selectionChanged();
00364     virtual void toolModeChanged();
00365     virtual void overlayModeChanged();
00366     virtual void zoomWheelsEnabledChanged();
00367 
00368     virtual void cancelClicked();
00369 
00370     virtual void progressCheckStalledTimerElapsed();
00371 
00372 protected:
00373     View(QWidget *, bool showProgress);
00374     virtual void paintEvent(QPaintEvent *e);
00375     virtual void drawSelections(QPainter &);
00376     virtual bool shouldLabelSelections() const { return true; }
00377     virtual bool render(QPainter &paint, int x0, int f0, int f1);
00378     virtual void setPaintFont(QPainter &paint);
00379     
00380     typedef std::vector<Layer *> LayerList;
00381 
00382     int getModelsSampleRate() const;
00383     bool areLayersScrollable() const;
00384     LayerList getScrollableBackLayers(bool testChanged, bool &changed) const;
00385     LayerList getNonScrollableFrontLayers(bool testChanged, bool &changed) const;
00386     int getZoomConstraintBlockSize(int blockSize,
00387                                       ZoomConstraint::RoundingDirection dir =
00388                                       ZoomConstraint::RoundNearest) const;
00389 
00390     // True if the top layer(s) use colours for meaningful things.  If
00391     // this is the case, selections will be shown using unfilled boxes
00392     // rather than with a translucent fill.
00393     bool areLayerColoursSignificant() const;
00394 
00395     // True if the top layer has a time axis on the x coordinate (this
00396     // is generally the case except for spectrum/slice layers).  It
00397     // will not be possible to make or display selections if this is
00398     // false.
00399     bool hasTopLayerTimeXAxis() const;
00400 
00401     bool setCentreFrame(int f, bool doEmit);
00402 
00403     void movePlayPointer(int f);
00404 
00405     void checkProgress(void *object);
00406     int getProgressBarWidth() const; // if visible
00407 
00408     int              m_centreFrame;
00409     int                 m_zoomLevel;
00410     bool                m_followPan;
00411     bool                m_followZoom;
00412     PlaybackFollowMode  m_followPlay;
00413     bool                m_followPlayIsDetached;
00414     int                 m_playPointerFrame;
00415     bool                m_lightBackground;
00416     bool                m_showProgress;
00417 
00418     QPixmap            *m_cache;
00419     int                 m_cacheCentreFrame;
00420     int                 m_cacheZoomLevel;
00421     bool                m_selectionCached;
00422 
00423     bool                m_deleting;
00424 
00425     LayerList           m_layerStack; // I don't own these, but see dtor note above
00426     LayerList           m_fixedOrderLayers;
00427     bool                m_haveSelectedLayer;
00428 
00429     QString             m_lastError;
00430 
00431     // caches for use in getScrollableBackLayers, getNonScrollableFrontLayers
00432     mutable LayerList m_lastScrollableBackLayers;
00433     mutable LayerList m_lastNonScrollableBackLayers;
00434 
00435     struct ProgressBarRec {
00436         QPushButton *cancel;
00437         QProgressBar *bar;
00438         int lastCheck;
00439         QTimer *checkTimer;
00440     };
00441     typedef std::map<Layer *, ProgressBarRec> ProgressMap;
00442     ProgressMap m_progressBars; // I own the ProgressBars
00443 
00444     ViewManager *m_manager; // I don't own this
00445     ViewPropertyContainer *m_propertyContainer; // I own this
00446 };
00447 
00448 
00449 // Use this for delegation, because we can't subclass from
00450 // PropertyContainer (which is a QObject) ourselves because of
00451 // ambiguity with QFrame parent
00452 
00453 class ViewPropertyContainer : public PropertyContainer
00454 {
00455     Q_OBJECT
00456 
00457 public:
00458     ViewPropertyContainer(View *v);
00459     virtual ~ViewPropertyContainer();
00460 
00461     PropertyList getProperties() const { return m_v->getProperties(); }
00462     QString getPropertyLabel(const PropertyName &n) const {
00463         return m_v->getPropertyLabel(n);
00464     }
00465     PropertyType getPropertyType(const PropertyName &n) const {
00466         return m_v->getPropertyType(n);
00467     }
00468     int getPropertyRangeAndValue(const PropertyName &n, int *min, int *max,
00469                                  int *deflt) const {
00470         return m_v->getPropertyRangeAndValue(n, min, max, deflt);
00471     }
00472     QString getPropertyValueLabel(const PropertyName &n, int value) const {
00473         return m_v->getPropertyValueLabel(n, value);
00474     }
00475     QString getPropertyContainerName() const {
00476         return m_v->getPropertyContainerName();
00477     }
00478     QString getPropertyContainerIconName() const {
00479         return m_v->getPropertyContainerIconName();
00480     }
00481 
00482 public slots:
00483     virtual void setProperty(const PropertyName &n, int value) {
00484         m_v->setProperty(n, value);
00485     }
00486 
00487 protected:
00488     View *m_v;
00489 };
00490 
00491 #endif
00492