Mercurial > hg > svcore
view base/Layer.h @ 40:b2d1a61ab916
* A bit more work on main window / document / commands stuff. This is still
pretty unstable.
* Enable CSV file reader also to read files with other separators (e.g. .lab
files with space separators)
* Show "(R)" on waveform display when resampling during playback
* Add ability to import additional audio files (can't process them yet)
* Fixes to spectrogram cache for multiple views
* Fix to avoid floating-point exception in sparse model when resolution not
set yet
author | Chris Cannam |
---|---|
date | Mon, 06 Mar 2006 17:20:25 +0000 |
parents | e1a0cf2dcc79 |
children | 2b6412c1e724 |
line wrap: on
line source
/* -*- c-basic-offset: 4 -*- vi:set ts=8 sts=4 sw=4: */ /* A waveform viewer and audio annotation editor. Chris Cannam, Queen Mary University of London, 2005-2006 This is experimental software. Not for distribution. */ #ifndef _LAYER_H_ #define _LAYER_H_ #include "PropertyContainer.h" #include "XmlExportable.h" #include "Selection.h" #include <QObject> #include <QRect> #include <QXmlAttributes> #include <map> class ZoomConstraint; class Model; class QPainter; class View; class QMouseEvent; /** * The base class for visual representations of the data found in a * Model. Layers are expected to be able to draw themselves onto a * View, and may also be editable. */ class Layer : public PropertyContainer, public XmlExportable { Q_OBJECT public: Layer(); virtual ~Layer(); virtual const Model *getModel() const = 0; virtual const ZoomConstraint *getZoomConstraint() const { return 0; } virtual void paint(View *, QPainter &, QRect) const = 0; enum VerticalPosition { PositionTop, PositionMiddle, PositionBottom }; virtual VerticalPosition getPreferredTimeRulerPosition() const { return PositionMiddle; } virtual VerticalPosition getPreferredFrameCountPosition() const { return PositionBottom; } virtual QString getPropertyContainerIconName() const; virtual QString getPropertyContainerName() const { return objectName(); } virtual int getVerticalScaleWidth(View *, QPainter &) const { return 0; } virtual void paintVerticalScale(View *, QPainter &, QRect) const { } virtual QString getFeatureDescription(View *, QPoint &) const { return ""; } //!!! We also need a method (like the vertical scale method) for //drawing additional scales like a colour scale. That is, unless //all applicable layers can actually do this from //paintVerticalScale as well? enum SnapType { SnapLeft, SnapRight, SnapNearest, SnapNeighbouring }; /** * Adjust the given frame to snap to the nearest feature, if * possible. * * If snap is SnapLeft or SnapRight, adjust the frame to match * that of the nearest feature in the given direction regardless * of how far away it is. If snap is SnapNearest, adjust the * frame to that of the nearest feature in either direction. If * snap is SnapNeighbouring, adjust the frame to that of the * nearest feature if it is close, and leave it alone (returning * false) otherwise. SnapNeighbouring should always choose the * same feature that would be used in an editing operation through * calls to editStart etc. * * Return true if a suitable feature was found and frame adjusted * accordingly. Return false if no suitable feature was * available. Also return the resolution of the model in this * layer in sample frames. */ virtual bool snapToFeatureFrame(View *v, int &frame, size_t &resolution, SnapType snap) const { resolution = 1; return false; } // Draw and edit modes: // // Layer needs to get actual mouse events, I guess. Draw mode is // probably the easier. virtual void drawStart(View *, QMouseEvent *) { } virtual void drawDrag(View *, QMouseEvent *) { } virtual void drawEnd(View *, QMouseEvent *) { } virtual void editStart(View *, QMouseEvent *) { } virtual void editDrag(View *, QMouseEvent *) { } virtual void editEnd(View *, QMouseEvent *) { } virtual void editOpen(View *, QMouseEvent *) { } // on double-click virtual void moveSelection(Selection s, size_t newStartFrame) { } virtual void resizeSelection(Selection s, Selection newSize) { } virtual void deleteSelection(Selection s) { } // Text mode: // // Label nearest feature. We need to get the feature coordinates // and current label from the layer, and then the pane can pop up // a little text entry dialog at the right location. Or we edit // in place? Probably the dialog is easier. /** * This should return true if the layer can safely be scrolled * automatically by a given view (simply copying the existing data * and then refreshing the exposed area) without altering its * meaning. For the view widget as a whole this is usually not * possible because of invariant (non-scrolling) material * displayed over the top, but the widget may be able to optimise * scrolling better if it is known that individual views can be * scrolled safely in this way. */ virtual bool isLayerScrollable(const View *) const { return true; } /** * This should return true if the layer completely obscures any * underlying layers. It's used to determine whether the view can * safely draw any selection rectangles under the layer instead of * over it, in the case where the layer is not scrollable and * therefore needs to be redrawn each time (so that the selection * rectangle can be cached). */ virtual bool isLayerOpaque() const { return false; } /** * This should return true if the layer can be edited by the user. * If this is the case, the appropriate edit tools may be made * available by the application and the layer's drawStart/Drag/End * and editStart/Drag/End methods should be implemented. */ virtual bool isLayerEditable() const { return false; } /** * Return the proportion of background work complete in drawing * this view, as a percentage -- in most cases this will be the * value returned by pointer from a call to the underlying model's * isReady(int *) call. The widget may choose to show a progress * meter if it finds that this returns < 100 at any given moment. */ virtual int getCompletion() const { return 100; } virtual void setObjectName(const QString &name); /** * Convert the layer's data (though not those of the model it * refers to) into an XML string for file output. This class * implements the basic name/type/model-id output; subclasses will * typically call this superclass implementation with extra * attributes describing their particular properties. */ virtual QString toXmlString(QString indent = "", QString extraAttributes = "") const; /** * Set the particular properties of a layer (those specific to the * subclass) from a set of XML attributes. This is the effective * inverse of the toXmlString method. */ virtual void setProperties(const QXmlAttributes &) = 0; /** * Indicate that a layer is not currently visible in the given * view and is not expected to become visible in the near future * (for example because the user has explicitly removed or hidden * it). The layer may respond by (for example) freeing any cache * memory it is using, until next time its paint method is called, * when it should set itself un-dormant again. */ virtual void setLayerDormant(const View *v, bool dormant) { m_dormancy[v] = dormant; } /** * Return whether the layer is dormant (i.e. hidden) in the given * view. */ virtual bool isLayerDormant(const View *v) const { if (m_dormancy.find(v) == m_dormancy.end()) return false; return m_dormancy.find(v)->second; } virtual PlayParameters *getPlayParameters(); public slots: void showLayer(View *, bool show); signals: void modelChanged(); void modelCompletionChanged(); void modelChanged(size_t startFrame, size_t endFrame); void modelReplaced(); void layerParametersChanged(); void layerNameChanged(); protected: mutable std::map<const void *, bool> m_dormancy; }; #endif