Chris@0: /* -*- c-basic-offset: 4 -*- vi:set ts=8 sts=4 sw=4: */ Chris@0: Chris@0: /* Chris@0: A waveform viewer and audio annotation editor. Chris@2: Chris Cannam, Queen Mary University of London, 2005-2006 Chris@0: Chris@0: This is experimental software. Not for distribution. Chris@0: */ Chris@0: Chris@0: #ifndef _CANVAS_H_ Chris@0: #define _CANVAS_H_ Chris@0: Chris@0: #include Chris@0: #include Chris@0: Chris@0: #include "base/ZoomConstraint.h" Chris@0: #include "base/PropertyContainer.h" Chris@8: #include "base/ViewManager.h" Chris@3: #include "base/XmlExportable.h" Chris@0: Chris@0: class Layer; Chris@0: Chris@0: #include Chris@0: Chris@0: /** Chris@0: * View is the base class of widgets that display one or more Chris@0: * overlaid views of data against a horizontal time scale. Chris@0: * Chris@0: * A View may have any number of attached Layers, each of which Chris@0: * is expected to have one data Model (although multiple views may Chris@0: * share the same model). Chris@0: * Chris@0: * A View may be panned in time and zoomed, although the Chris@0: * mechanisms for doing so (as well as any other operations and Chris@0: * properties available) depend on the subclass. Chris@0: */ Chris@0: Chris@0: class View : public QFrame, Chris@3: public PropertyContainer, Chris@3: public XmlExportable Chris@0: { Chris@0: Q_OBJECT Chris@0: Chris@0: public: Chris@0: /** Chris@0: * Deleting a View deletes all its views. However, it is Chris@0: * also acceptable for the views to be deleted by other code (in Chris@0: * which case they will remove themselves from this View Chris@0: * automatically), or to be removed explicitly without deleting Chris@0: * using removeLayer. Chris@0: */ Chris@0: virtual ~View(); Chris@0: Chris@0: /** Chris@0: * Retrieve the first visible sample frame on the widget. Chris@0: * This is a calculated value based on the centre-frame, widget Chris@0: * width and zoom level. The result may be negative. Chris@0: */ Chris@0: virtual long getStartFrame() const; Chris@0: Chris@0: /** Chris@0: * Set the widget pan based on the given first visible frame. The Chris@0: * frame value may be negative. Chris@0: */ Chris@0: virtual void setStartFrame(long); Chris@0: Chris@0: /** Chris@0: * Return the centre frame of the visible widget. This is an Chris@0: * exact value that does not depend on the zoom block size. Other Chris@0: * frame values (start, end) are calculated from this based on the Chris@0: * zoom and other factors. Chris@0: */ Chris@0: virtual size_t getCentreFrame() const { return m_centreFrame; } Chris@0: Chris@0: /** Chris@0: * Set the centre frame of the visible widget. Chris@0: */ Chris@0: virtual void setCentreFrame(size_t f) { setCentreFrame(f, true); } Chris@0: Chris@0: /** Chris@0: * Retrieve the last visible sample frame on the widget. Chris@0: * This is a calculated value based on the centre-frame, widget Chris@0: * width and zoom level. Chris@0: */ Chris@0: virtual size_t getEndFrame() const; Chris@0: Chris@0: /** Chris@0: * Return the zoom level, i.e. the number of frames per pixel. Chris@0: */ Chris@0: virtual int getZoomLevel() const { return m_zoomLevel; } Chris@0: Chris@0: /** Chris@0: * Set the zoom level, i.e. the number of frames per pixel. The Chris@0: * centre frame will be unchanged; the start and end frames will Chris@0: * change. Chris@0: */ Chris@0: virtual void setZoomLevel(size_t z); Chris@0: Chris@0: /** Chris@0: * Zoom in or out. Chris@0: */ Chris@0: virtual void zoom(bool in); Chris@0: Chris@0: virtual void addLayer(Layer *v); Chris@0: virtual void removeLayer(Layer *v); // does not delete the layer Chris@0: virtual int getLayerCount() const { return m_layers.size(); } Chris@0: Chris@0: /** Chris@0: * Return a layer, counted in stacking order. That is, layer 0 is Chris@0: * the bottom layer and layer "getLayerCount()-1" is the top one. Chris@0: */ Chris@0: virtual Layer *getLayer(int n) { return m_layers[n]; } Chris@0: Chris@8: /** Chris@8: * Return the layer last selected by the user. This is normally Chris@8: * the top layer, the same as getLayer(getLayerCount()-1). Chris@8: * However, if the user has selected the pane itself more recently Chris@8: * than any of the layers on it, this function will return 0. It Chris@8: * will also return 0 if there are no layers. Chris@8: */ Chris@8: virtual Layer *getSelectedLayer(); Chris@8: Chris@0: virtual void setViewManager(ViewManager *m); Chris@0: Chris@0: virtual void setFollowGlobalPan(bool f); Chris@0: virtual bool getFollowGlobalPan() const { return m_followPan; } Chris@0: Chris@0: virtual void setFollowGlobalZoom(bool f); Chris@0: virtual bool getFollowGlobalZoom() const { return m_followZoom; } Chris@0: Chris@0: virtual void setLightBackground(bool lb) { m_lightBackground = lb; } Chris@0: virtual bool hasLightBackground() const { return m_lightBackground; } Chris@0: Chris@0: virtual bool shouldIlluminateLocalFeatures(const Layer *, QPoint &) { Chris@0: return false; Chris@0: } Chris@0: Chris@0: enum PlaybackFollowMode { Chris@0: PlaybackScrollContinuous, Chris@0: PlaybackScrollPage, Chris@0: PlaybackIgnore Chris@0: }; Chris@0: virtual void setPlaybackFollow(PlaybackFollowMode m); Chris@0: virtual PlaybackFollowMode getPlaybackFollow() const { return m_followPlay; } Chris@0: Chris@0: virtual PropertyList getProperties() const; Chris@0: virtual PropertyType getPropertyType(const PropertyName &) const; Chris@0: virtual int getPropertyRangeAndValue(const PropertyName &, Chris@0: int *min, int *max) const; Chris@0: virtual QString getPropertyValueLabel(const PropertyName &, Chris@0: int value) const; Chris@0: virtual void setProperty(const PropertyName &, int value); Chris@0: Chris@0: virtual size_t getPropertyContainerCount() const; Chris@0: virtual const PropertyContainer *getPropertyContainer(size_t i) const; Chris@0: virtual PropertyContainer *getPropertyContainer(size_t i); Chris@0: Chris@0: virtual QString getPropertyContainerName() const { Chris@0: return objectName(); Chris@0: } Chris@0: Chris@3: virtual QString toXmlString(QString indent = "", Chris@3: QString extraAttributes = "") const; Chris@3: Chris@0: signals: Chris@0: void propertyContainerAdded(PropertyContainer *pc); Chris@0: void propertyContainerRemoved(PropertyContainer *pc); Chris@0: void propertyContainerPropertyChanged(PropertyContainer *pc); Chris@0: void propertyContainerNameChanged(PropertyContainer *pc); Chris@0: Chris@0: void centreFrameChanged(void *, unsigned long, bool); Chris@0: void zoomLevelChanged(void *, unsigned long, bool); Chris@0: Chris@0: public slots: Chris@0: virtual void modelChanged(); Chris@0: virtual void modelChanged(size_t startFrame, size_t endFrame); Chris@0: virtual void modelCompletionChanged(); Chris@0: virtual void modelReplaced(); Chris@0: virtual void layerParametersChanged(); Chris@0: virtual void layerNameChanged(); Chris@0: Chris@0: virtual void viewManagerCentreFrameChanged(void *, unsigned long, bool); Chris@0: virtual void viewManagerPlaybackFrameChanged(unsigned long); Chris@0: virtual void viewManagerZoomLevelChanged(void *, unsigned long, bool); Chris@0: Chris@0: virtual void propertyContainerSelected(PropertyContainer *pc); Chris@0: Chris@9: virtual void selectionChanged(); Chris@8: virtual void toolModeChanged(); Chris@8: Chris@0: protected: Chris@0: View(QWidget *, bool showProgress); Chris@0: virtual void paintEvent(QPaintEvent *e); Chris@9: virtual void drawSelections(QPainter &); Chris@10: virtual bool shouldLabelSelections() const { return true; } Chris@0: Chris@0: typedef std::vector LayerList; Chris@0: Chris@0: size_t getModelsStartFrame() const; Chris@0: size_t getModelsEndFrame() const; Chris@0: int getModelsSampleRate() const; Chris@0: bool areLayersScrollable() const; Chris@0: LayerList getScrollableBackLayers(bool &changed) const; Chris@0: LayerList getNonScrollableFrontLayers(bool &changed) const; Chris@0: size_t getZoomConstraintBlockSize(size_t blockSize, Chris@0: ZoomConstraint::RoundingDirection dir = Chris@0: ZoomConstraint::RoundNearest) const; Chris@0: Chris@10: bool setCentreFrame(size_t f, bool doEmit); Chris@0: Chris@0: void checkProgress(void *object); Chris@0: Chris@3: size_t m_centreFrame; Chris@3: int m_zoomLevel; Chris@3: bool m_newModel; Chris@3: bool m_followPan; Chris@3: bool m_followZoom; Chris@3: PlaybackFollowMode m_followPlay; Chris@3: size_t m_playPointerFrame; Chris@3: bool m_lightBackground; Chris@3: bool m_showProgress; Chris@0: Chris@3: QPixmap *m_cache; Chris@3: size_t m_cacheCentreFrame; Chris@3: int m_cacheZoomLevel; Chris@9: bool m_selectionCached; Chris@0: Chris@3: bool m_deleting; Chris@0: Chris@3: LayerList m_layers; // I don't own these, but see dtor note above Chris@8: bool m_haveSelectedLayer; Chris@0: Chris@0: // caches for use in getScrollableBackLayers, getNonScrollableFrontLayers Chris@0: mutable LayerList m_lastScrollableBackLayers; Chris@0: mutable LayerList m_lastNonScrollableBackLayers; Chris@0: Chris@0: class LayerProgressBar : public QProgressBar { Chris@0: public: Chris@0: LayerProgressBar(QWidget *parent) : QProgressBar(parent) { } Chris@0: virtual QString text() const { return m_text; } Chris@0: virtual void setText(QString text) { m_text = text; } Chris@0: protected: Chris@0: QString m_text; Chris@0: }; Chris@0: Chris@0: typedef std::map ProgressMap; Chris@0: ProgressMap m_progressBars; // I own the ProgressBars Chris@0: Chris@0: ViewManager *m_manager; // I don't own this Chris@0: }; Chris@0: Chris@0: #endif Chris@0: