Chris@0: 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 _VIEWER_H_ Chris@0: #define _VIEWER_H_ Chris@0: Chris@0: #include "PropertyContainer.h" Chris@3: #include "XmlExportable.h" Chris@0: Chris@0: #include Chris@0: #include Chris@6: #include Chris@0: Chris@0: class ZoomConstraint; Chris@0: class Model; Chris@0: class QPainter; Chris@0: class View; Chris@0: Chris@0: /** Chris@0: * The base class for visual representations of the data found in a Chris@0: * Model. Layers are expected to be able to draw themselves onto a Chris@0: * View, and may also be editable. Chris@0: */ Chris@0: Chris@0: class Layer : public QObject, Chris@3: public PropertyContainer, Chris@3: public XmlExportable Chris@0: { Chris@0: Q_OBJECT Chris@0: Chris@0: public: Chris@0: Layer(View *w); Chris@0: virtual ~Layer(); Chris@0: Chris@0: virtual const Model *getModel() const = 0; Chris@0: virtual const ZoomConstraint *getZoomConstraint() const { return 0; } Chris@0: virtual void paint(QPainter &, QRect) const = 0; Chris@0: Chris@0: enum VerticalPosition { Chris@0: PositionTop, PositionMiddle, PositionBottom Chris@0: }; Chris@0: virtual VerticalPosition getPreferredTimeRulerPosition() const { Chris@0: return PositionMiddle; Chris@0: } Chris@0: virtual VerticalPosition getPreferredFrameCountPosition() const { Chris@0: return PositionBottom; Chris@0: } Chris@0: Chris@0: virtual QString getPropertyContainerName() const { Chris@0: return objectName(); Chris@0: } Chris@0: Chris@0: virtual int getVerticalScaleWidth(QPainter &) const { return 0; } Chris@0: virtual void paintVerticalScale(QPainter &, QRect) const { } Chris@0: Chris@8: //!!! I don't like these. The layer should return a structured Chris@8: //string-based description list and the pane should render it Chris@8: //itself. Chris@8: Chris@0: virtual QRect getFeatureDescriptionRect(QPainter &, QPoint) const { Chris@0: return QRect(0, 0, 0, 0); Chris@0: } Chris@0: virtual void paintLocalFeatureDescription(QPainter &, QRect, QPoint) const { Chris@0: } Chris@0: Chris@8: //!!! We also need a method (like the vertical scale method) for Chris@8: //drawing additional scales like a colour scale. That is, unless Chris@8: //all applicable layers can actually do this from Chris@8: //paintVerticalScale as well? Chris@8: Chris@8: // Select mode: Chris@8: // Chris@8: //!!! Next, a method that gets the frame of the nearest feature in Chris@8: //a particular snap direction. This would be used for selection Chris@8: //mode, where we're selecting from the waveform based on feature Chris@8: //location. Do we need multi-select on features as well? This is Chris@8: //an issue; if you select a feature are you selecting that feature Chris@8: //(in which case what do you do with it?) or a section of the Chris@8: //underlying waveform? Chris@8: Chris@8: virtual int getNearestFeatureFrame(int frame, Chris@8: size_t &resolution, Chris@8: bool snapRight = true) const { Chris@8: resolution = 1; Chris@8: return frame; Chris@8: } Chris@8: Chris@8: // Paint and edit modes: Chris@8: // Chris@8: // Layer needs to get actual mouse events, I guess. Paint mode is Chris@8: // probably the easier. Chris@8: Chris@8: // Text mode: Chris@8: // Chris@8: // Label nearest feature. We need to get the feature coordinates Chris@8: // and current label from the layer, and then the pane can pop up Chris@8: // a little text entry dialog at the right location. Or we edit Chris@8: // in place? Probably the dialog is easier. Chris@8: Chris@0: /** Chris@0: * This should return true if the view can safely be scrolled Chris@0: * automatically by the widget (simply copying the existing data Chris@0: * and then refreshing the exposed area) without altering its Chris@0: * meaning. For the widget as a whole this is usually not Chris@0: * possible because of invariant (non-scrolling) material Chris@0: * displayed over the top, but the widget may be able to optimise Chris@0: * scrolling better if it is known that individual views can be Chris@0: * scrolled safely in this way. Chris@0: */ Chris@0: virtual bool isLayerScrollable() const { return true; } Chris@0: Chris@0: /** Chris@10: * This should return true if the layer completely obscures any Chris@10: * underlying layers. It's used to determine whether the view can Chris@10: * safely draw any selection rectangles under the layer instead of Chris@10: * over it, in the case where the layer is not scrollable and Chris@10: * therefore needs to be redrawn each time (so that the selection Chris@10: * rectangle can be cached). Chris@10: */ Chris@10: virtual bool isLayerOpaque() const { return false; } Chris@10: Chris@10: /** Chris@0: * Return the proportion of background work complete in drawing Chris@0: * this view, as a percentage -- in most cases this will be the Chris@0: * value returned by pointer from a call to the underlying model's Chris@0: * isReady(int *) call. The widget may choose to show a progress Chris@0: * meter if it finds that this returns < 100 at any given moment. Chris@0: */ Chris@0: virtual int getCompletion() const { return 100; } Chris@0: Chris@0: virtual void setObjectName(const QString &name); Chris@0: Chris@7: /** Chris@7: * Convert the layer's data (though not those of the model it Chris@7: * refers to) into an XML string for file output. This class Chris@7: * implements the basic name/type/model-id output; subclasses will Chris@7: * typically call this superclass implementation with extra Chris@7: * attributes describing their particular properties. Chris@7: */ Chris@3: virtual QString toXmlString(QString indent = "", Chris@3: QString extraAttributes = "") const; Chris@3: Chris@7: /** Chris@7: * Set the particular properties of a layer (those specific to the Chris@7: * subclass) from a set of XML attributes. This is the effective Chris@7: * inverse of the toXmlString method. Chris@7: */ Chris@6: virtual void setProperties(const QXmlAttributes &) = 0; Chris@6: Chris@0: signals: Chris@0: void modelChanged(); Chris@0: void modelCompletionChanged(); Chris@0: void modelChanged(size_t startFrame, size_t endFrame); Chris@0: void modelReplaced(); Chris@0: Chris@0: void layerParametersChanged(); Chris@0: void layerNameChanged(); Chris@0: Chris@0: protected: Chris@0: View *m_view; Chris@0: }; Chris@0: Chris@0: #endif Chris@0: