annotate base/View.h @ 33:51e158b505da

* Rearrange spectrogram cacheing so that gain, normalization, instantaneous frequency calculations etc can be done from the cached data (increasing the size of the cache, but also the usability).
author Chris Cannam
date Thu, 23 Feb 2006 18:01:31 +0000
parents 4afaf0df4d51
children aaf73f7309f2
rev   line source
Chris@0 1 /* -*- c-basic-offset: 4 -*- vi:set ts=8 sts=4 sw=4: */
Chris@0 2
Chris@0 3 /*
Chris@0 4 A waveform viewer and audio annotation editor.
Chris@2 5 Chris Cannam, Queen Mary University of London, 2005-2006
Chris@0 6
Chris@0 7 This is experimental software. Not for distribution.
Chris@0 8 */
Chris@0 9
Chris@0 10 #ifndef _CANVAS_H_
Chris@0 11 #define _CANVAS_H_
Chris@0 12
Chris@0 13 #include <QFrame>
Chris@0 14 #include <QProgressBar>
Chris@0 15
Chris@0 16 #include "base/ZoomConstraint.h"
Chris@0 17 #include "base/PropertyContainer.h"
Chris@8 18 #include "base/ViewManager.h"
Chris@3 19 #include "base/XmlExportable.h"
Chris@0 20
Chris@0 21 class Layer;
Chris@29 22 class ViewPropertyContainer;
Chris@0 23
Chris@0 24 #include <map>
Chris@0 25
Chris@0 26 /**
Chris@0 27 * View is the base class of widgets that display one or more
Chris@0 28 * overlaid views of data against a horizontal time scale.
Chris@0 29 *
Chris@0 30 * A View may have any number of attached Layers, each of which
Chris@0 31 * is expected to have one data Model (although multiple views may
Chris@0 32 * share the same model).
Chris@0 33 *
Chris@0 34 * A View may be panned in time and zoomed, although the
Chris@0 35 * mechanisms for doing so (as well as any other operations and
Chris@0 36 * properties available) depend on the subclass.
Chris@0 37 */
Chris@0 38
Chris@0 39 class View : public QFrame,
Chris@3 40 public XmlExportable
Chris@0 41 {
Chris@0 42 Q_OBJECT
Chris@0 43
Chris@0 44 public:
Chris@0 45 /**
Chris@0 46 * Deleting a View deletes all its views. However, it is
Chris@0 47 * also acceptable for the views to be deleted by other code (in
Chris@0 48 * which case they will remove themselves from this View
Chris@0 49 * automatically), or to be removed explicitly without deleting
Chris@0 50 * using removeLayer.
Chris@0 51 */
Chris@0 52 virtual ~View();
Chris@0 53
Chris@0 54 /**
Chris@0 55 * Retrieve the first visible sample frame on the widget.
Chris@0 56 * This is a calculated value based on the centre-frame, widget
Chris@0 57 * width and zoom level. The result may be negative.
Chris@0 58 */
Chris@0 59 virtual long getStartFrame() const;
Chris@0 60
Chris@0 61 /**
Chris@0 62 * Set the widget pan based on the given first visible frame. The
Chris@0 63 * frame value may be negative.
Chris@0 64 */
Chris@0 65 virtual void setStartFrame(long);
Chris@0 66
Chris@0 67 /**
Chris@0 68 * Return the centre frame of the visible widget. This is an
Chris@0 69 * exact value that does not depend on the zoom block size. Other
Chris@0 70 * frame values (start, end) are calculated from this based on the
Chris@0 71 * zoom and other factors.
Chris@0 72 */
Chris@0 73 virtual size_t getCentreFrame() const { return m_centreFrame; }
Chris@0 74
Chris@0 75 /**
Chris@0 76 * Set the centre frame of the visible widget.
Chris@0 77 */
Chris@0 78 virtual void setCentreFrame(size_t f) { setCentreFrame(f, true); }
Chris@0 79
Chris@0 80 /**
Chris@0 81 * Retrieve the last visible sample frame on the widget.
Chris@0 82 * This is a calculated value based on the centre-frame, widget
Chris@0 83 * width and zoom level.
Chris@0 84 */
Chris@0 85 virtual size_t getEndFrame() const;
Chris@0 86
Chris@0 87 /**
Chris@15 88 * Return the pixel x-coordinate corresponding to a given sample
Chris@15 89 * frame (which may be negative).
Chris@15 90 */
Chris@15 91 int getXForFrame(long frame) const;
Chris@15 92
Chris@15 93 /**
Chris@15 94 * Return the closest frame to the given pixel x-coordinate.
Chris@15 95 */
Chris@15 96 long getFrameForX(int x) const;
Chris@15 97
Chris@15 98 /**
Chris@33 99 * Return the pixel y-coordinate corresponding to a given
Chris@33 100 * frequency, if the frequency range is as specified. This does
Chris@33 101 * not imply any policy about layer frequency ranges, but it might
Chris@33 102 * be useful for layers to match theirs up if desired.
Chris@33 103 *
Chris@33 104 * Not thread-safe in logarithmic mode. Call only from GUI thread.
Chris@33 105 */
Chris@33 106 float getYForFrequency(float frequency, float minFreq, float maxFreq,
Chris@33 107 bool logarithmic) const;
Chris@33 108
Chris@33 109 /**
Chris@33 110 * Return the closest frequency to the given pixel y-coordinate,
Chris@33 111 * if the frequency range is as specified.
Chris@33 112 *
Chris@33 113 * Not thread-safe in logarithmic mode. Call only from GUI thread.
Chris@33 114 */
Chris@33 115 float getFrequencyForY(int y, float minFreq, float maxFreq,
Chris@33 116 bool logarithmic) const;
Chris@33 117
Chris@33 118 /**
Chris@22 119 * Return the zoom level, i.e. the number of frames per pixel
Chris@0 120 */
Chris@22 121 int getZoomLevel() const;
Chris@0 122
Chris@0 123 /**
Chris@0 124 * Set the zoom level, i.e. the number of frames per pixel. The
Chris@0 125 * centre frame will be unchanged; the start and end frames will
Chris@0 126 * change.
Chris@0 127 */
Chris@0 128 virtual void setZoomLevel(size_t z);
Chris@0 129
Chris@0 130 /**
Chris@0 131 * Zoom in or out.
Chris@0 132 */
Chris@0 133 virtual void zoom(bool in);
Chris@0 134
Chris@12 135 /**
Chris@12 136 * Scroll left or right by a smallish or largish amount.
Chris@12 137 */
Chris@12 138 virtual void scroll(bool right, bool lots);
Chris@12 139
Chris@0 140 virtual void addLayer(Layer *v);
Chris@0 141 virtual void removeLayer(Layer *v); // does not delete the layer
Chris@0 142 virtual int getLayerCount() const { return m_layers.size(); }
Chris@0 143
Chris@0 144 /**
Chris@0 145 * Return a layer, counted in stacking order. That is, layer 0 is
Chris@0 146 * the bottom layer and layer "getLayerCount()-1" is the top one.
Chris@0 147 */
Chris@0 148 virtual Layer *getLayer(int n) { return m_layers[n]; }
Chris@0 149
Chris@8 150 /**
Chris@8 151 * Return the layer last selected by the user. This is normally
Chris@8 152 * the top layer, the same as getLayer(getLayerCount()-1).
Chris@8 153 * However, if the user has selected the pane itself more recently
Chris@8 154 * than any of the layers on it, this function will return 0. It
Chris@8 155 * will also return 0 if there are no layers.
Chris@8 156 */
Chris@8 157 virtual Layer *getSelectedLayer();
Chris@8 158
Chris@0 159 virtual void setViewManager(ViewManager *m);
Chris@0 160
Chris@0 161 virtual void setFollowGlobalPan(bool f);
Chris@0 162 virtual bool getFollowGlobalPan() const { return m_followPan; }
Chris@0 163
Chris@0 164 virtual void setFollowGlobalZoom(bool f);
Chris@0 165 virtual bool getFollowGlobalZoom() const { return m_followZoom; }
Chris@0 166
Chris@0 167 virtual void setLightBackground(bool lb) { m_lightBackground = lb; }
Chris@0 168 virtual bool hasLightBackground() const { return m_lightBackground; }
Chris@0 169
Chris@0 170 virtual bool shouldIlluminateLocalFeatures(const Layer *, QPoint &) {
Chris@0 171 return false;
Chris@0 172 }
Chris@0 173
Chris@0 174 enum PlaybackFollowMode {
Chris@0 175 PlaybackScrollContinuous,
Chris@0 176 PlaybackScrollPage,
Chris@0 177 PlaybackIgnore
Chris@0 178 };
Chris@0 179 virtual void setPlaybackFollow(PlaybackFollowMode m);
Chris@0 180 virtual PlaybackFollowMode getPlaybackFollow() const { return m_followPlay; }
Chris@0 181
Chris@30 182 typedef PropertyContainer::PropertyName PropertyName;
Chris@30 183
Chris@29 184 // We implement the PropertyContainer API, although we don't
Chris@29 185 // actually subclass PropertyContainer. We have our own
Chris@29 186 // PropertyContainer that we can return on request that just
Chris@29 187 // delegates back to us.
Chris@29 188 virtual PropertyContainer::PropertyList getProperties() const;
Chris@30 189 virtual PropertyContainer::PropertyType getPropertyType(const PropertyName &) const;
Chris@30 190 virtual int getPropertyRangeAndValue(const PropertyName &,
Chris@29 191 int *min, int *max) const;
Chris@30 192 virtual QString getPropertyValueLabel(const PropertyName &,
Chris@0 193 int value) const;
Chris@30 194 virtual void setProperty(const PropertyName &, int value);
Chris@0 195 virtual QString getPropertyContainerName() const {
Chris@0 196 return objectName();
Chris@0 197 }
Chris@30 198 virtual QString getPropertyContainerIconName() const = 0;
Chris@0 199
Chris@29 200 virtual size_t getPropertyContainerCount() const;
Chris@29 201
Chris@29 202 virtual const PropertyContainer *getPropertyContainer(size_t i) const;
Chris@29 203 virtual PropertyContainer *getPropertyContainer(size_t i);
Chris@29 204
Chris@3 205 virtual QString toXmlString(QString indent = "",
Chris@3 206 QString extraAttributes = "") const;
Chris@3 207
Chris@0 208 signals:
Chris@0 209 void propertyContainerAdded(PropertyContainer *pc);
Chris@0 210 void propertyContainerRemoved(PropertyContainer *pc);
Chris@0 211 void propertyContainerPropertyChanged(PropertyContainer *pc);
Chris@0 212 void propertyContainerNameChanged(PropertyContainer *pc);
Chris@30 213 void propertyChanged(PropertyName);
Chris@0 214
Chris@0 215 void centreFrameChanged(void *, unsigned long, bool);
Chris@0 216 void zoomLevelChanged(void *, unsigned long, bool);
Chris@0 217
Chris@0 218 public slots:
Chris@0 219 virtual void modelChanged();
Chris@0 220 virtual void modelChanged(size_t startFrame, size_t endFrame);
Chris@0 221 virtual void modelCompletionChanged();
Chris@0 222 virtual void modelReplaced();
Chris@0 223 virtual void layerParametersChanged();
Chris@0 224 virtual void layerNameChanged();
Chris@0 225
Chris@0 226 virtual void viewManagerCentreFrameChanged(void *, unsigned long, bool);
Chris@0 227 virtual void viewManagerPlaybackFrameChanged(unsigned long);
Chris@0 228 virtual void viewManagerZoomLevelChanged(void *, unsigned long, bool);
Chris@0 229
Chris@0 230 virtual void propertyContainerSelected(PropertyContainer *pc);
Chris@0 231
Chris@9 232 virtual void selectionChanged();
Chris@8 233 virtual void toolModeChanged();
Chris@8 234
Chris@0 235 protected:
Chris@0 236 View(QWidget *, bool showProgress);
Chris@0 237 virtual void paintEvent(QPaintEvent *e);
Chris@9 238 virtual void drawSelections(QPainter &);
Chris@10 239 virtual bool shouldLabelSelections() const { return true; }
Chris@0 240
Chris@0 241 typedef std::vector<Layer *> LayerList;
Chris@0 242
Chris@0 243 size_t getModelsStartFrame() const;
Chris@0 244 size_t getModelsEndFrame() const;
Chris@0 245 int getModelsSampleRate() const;
Chris@0 246 bool areLayersScrollable() const;
Chris@31 247 LayerList getScrollableBackLayers(bool testChanged, bool &changed) const;
Chris@31 248 LayerList getNonScrollableFrontLayers(bool testChanged, bool &changed) const;
Chris@0 249 size_t getZoomConstraintBlockSize(size_t blockSize,
Chris@0 250 ZoomConstraint::RoundingDirection dir =
Chris@0 251 ZoomConstraint::RoundNearest) const;
Chris@0 252
Chris@10 253 bool setCentreFrame(size_t f, bool doEmit);
Chris@0 254
Chris@0 255 void checkProgress(void *object);
Chris@0 256
Chris@3 257 size_t m_centreFrame;
Chris@3 258 int m_zoomLevel;
Chris@3 259 bool m_followPan;
Chris@3 260 bool m_followZoom;
Chris@3 261 PlaybackFollowMode m_followPlay;
Chris@3 262 size_t m_playPointerFrame;
Chris@3 263 bool m_lightBackground;
Chris@3 264 bool m_showProgress;
Chris@0 265
Chris@3 266 QPixmap *m_cache;
Chris@3 267 size_t m_cacheCentreFrame;
Chris@3 268 int m_cacheZoomLevel;
Chris@9 269 bool m_selectionCached;
Chris@0 270
Chris@3 271 bool m_deleting;
Chris@0 272
Chris@3 273 LayerList m_layers; // I don't own these, but see dtor note above
Chris@8 274 bool m_haveSelectedLayer;
Chris@0 275
Chris@0 276 // caches for use in getScrollableBackLayers, getNonScrollableFrontLayers
Chris@0 277 mutable LayerList m_lastScrollableBackLayers;
Chris@0 278 mutable LayerList m_lastNonScrollableBackLayers;
Chris@0 279
Chris@0 280 class LayerProgressBar : public QProgressBar {
Chris@0 281 public:
Chris@16 282 LayerProgressBar(QWidget *parent);
Chris@0 283 virtual QString text() const { return m_text; }
Chris@0 284 virtual void setText(QString text) { m_text = text; }
Chris@0 285 protected:
Chris@0 286 QString m_text;
Chris@0 287 };
Chris@0 288
Chris@0 289 typedef std::map<Layer *, LayerProgressBar *> ProgressMap;
Chris@0 290 ProgressMap m_progressBars; // I own the ProgressBars
Chris@0 291
Chris@0 292 ViewManager *m_manager; // I don't own this
Chris@29 293 ViewPropertyContainer *m_propertyContainer; // I own this
Chris@29 294 };
Chris@29 295
Chris@29 296
Chris@29 297 // Use this for delegation, because we can't subclass from
Chris@29 298 // PropertyContainer (which is a QObject) ourselves because of
Chris@29 299 // ambiguity with QFrame parent
Chris@29 300
Chris@29 301 class ViewPropertyContainer : public PropertyContainer
Chris@29 302 {
Chris@29 303 Q_OBJECT
Chris@29 304
Chris@29 305 public:
Chris@29 306 ViewPropertyContainer(View *v);
Chris@29 307 PropertyList getProperties() const { return m_v->getProperties(); }
Chris@29 308 PropertyType getPropertyType(const PropertyName &n) const {
Chris@29 309 return m_v->getPropertyType(n);
Chris@29 310 }
Chris@29 311 int getPropertyRangeAndValue(const PropertyName &n, int *min, int *max) const {
Chris@29 312 return m_v->getPropertyRangeAndValue(n, min, max);
Chris@29 313 }
Chris@29 314 QString getPropertyValueLabel(const PropertyName &n, int value) const {
Chris@29 315 return m_v->getPropertyValueLabel(n, value);
Chris@29 316 }
Chris@29 317 QString getPropertyContainerName() const {
Chris@29 318 return m_v->getPropertyContainerName();
Chris@29 319 }
Chris@29 320 QString getPropertyContainerIconName() const {
Chris@30 321 return m_v->getPropertyContainerIconName();
Chris@29 322 }
Chris@29 323
Chris@29 324 public slots:
Chris@29 325 virtual void setProperty(const PropertyName &n, int value) {
Chris@29 326 m_v->setProperty(n, value);
Chris@29 327 }
Chris@29 328
Chris@29 329 protected:
Chris@29 330 View *m_v;
Chris@0 331 };
Chris@0 332
Chris@0 333 #endif
Chris@0 334