Chris@58: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ Chris@0: Chris@0: /* Chris@59: Sonic Visualiser Chris@59: An audio file viewer and annotation editor. Chris@59: Centre for Digital Music, Queen Mary, University of London. Chris@182: This file copyright 2006 Chris Cannam and QMUL. Chris@0: Chris@59: This program is free software; you can redistribute it and/or Chris@59: modify it under the terms of the GNU General Public License as Chris@59: published by the Free Software Foundation; either version 2 of the Chris@59: License, or (at your option) any later version. See the file Chris@59: COPYING included with this distribution for more information. Chris@0: */ Chris@0: Chris@1068: #ifndef COLOUR_3D_PLOT_LAYER_H Chris@1068: #define COLOUR_3D_PLOT_LAYER_H Chris@0: Chris@193: #include "SliceableLayer.h" Chris@1082: #include "VerticalBinLayer.h" Chris@0: Chris@1097: #include "ColourScale.h" Chris@1097: #include "Colour3DPlotRenderer.h" Chris@1097: Chris@128: #include "data/model/DenseThreeDimensionalModel.h" Chris@0: Chris@0: class View; Chris@0: class QPainter; Chris@0: class QImage; Chris@0: Chris@0: /** Chris@0: * This is a view that displays dense 3-D data (time, some sort of Chris@0: * binned y-axis range, value) as a colour plot with value mapped to Chris@0: * colour range. Its source is a DenseThreeDimensionalModel. Chris@0: * Chris@0: * This was the original implementation for the spectrogram view, but Chris@1068: * it was replaced for that purpose with a more efficient Chris@1068: * implementation that derived the spectrogram itself from a Chris@1068: * DenseTimeValueModel instead of using a three-dimensional model. Chris@0: */ Chris@1110: class Colour3DPlotLayer : public VerticalBinLayer Chris@0: { Chris@0: Q_OBJECT Chris@0: Chris@0: public: Chris@44: Colour3DPlotLayer(); Chris@0: ~Colour3DPlotLayer(); Chris@0: Chris@1469: ModelId getModel() const override { return m_model; } Chris@1469: Chris@1563: ModelId getExportModel(LayerGeometryProvider *) const override; Chris@1563: Chris@1469: const ZoomConstraint *getZoomConstraint() const override; Chris@1469: Chris@1469: void paint(LayerGeometryProvider *v, Chris@1469: QPainter &paint, QRect rect) const override; Chris@1406: void setSynchronousPainting(bool synchronous) override; Chris@0: Chris@1469: int getVerticalScaleWidth(LayerGeometryProvider *v, Chris@1469: bool, QPainter &) const override; Chris@1469: void paintVerticalScale(LayerGeometryProvider *v, Chris@1469: bool, QPainter &paint, QRect rect) const override; Chris@25: Chris@1469: QString getFeatureDescription(LayerGeometryProvider *v, Chris@1469: QPoint &) const override; Chris@25: Chris@1406: bool snapToFeatureFrame(LayerGeometryProvider *v, sv_frame_t &frame, Chris@1469: int &resolution, Chris@1547: SnapType snap, int ycoord) const override; Chris@24: Chris@1469: void setLayerDormant(const LayerGeometryProvider *v, Chris@1469: bool dormant) override; Chris@475: Chris@1406: bool isLayerScrollable(const LayerGeometryProvider *v) const override; Chris@25: Chris@1406: ColourSignificance getLayerColourSignificance() const override { Chris@287: return ColourHasMeaningfulValue; Chris@287: } Chris@183: Chris@1469: void setModel(ModelId model); // a DenseThreeDimensionalModel Chris@0: Chris@1469: int getCompletion(LayerGeometryProvider *) const override; Chris@24: Chris@1406: PropertyList getProperties() const override; Chris@1406: PropertyType getPropertyType(const PropertyName &) const override; Chris@1406: QString getPropertyLabel(const PropertyName &) const override; Chris@1406: QString getPropertyIconName(const PropertyName &) const override; Chris@1406: QString getPropertyGroupName(const PropertyName &) const override; Chris@1406: int getPropertyRangeAndValue(const PropertyName &, Chris@1469: int *min, int *max, int *deflt) const override; Chris@1406: QString getPropertyValueLabel(const PropertyName &, Chris@1469: int value) const override; Chris@1406: QString getPropertyValueIconName(const PropertyName &, Chris@1469: int value) const override; Chris@1406: RangeMapper *getNewPropertyRangeMapper(const PropertyName &) const override; Chris@1406: void setProperty(const PropertyName &, int value) override; Chris@1406: void setProperties(const QXmlAttributes &) override; Chris@11: Chris@1105: void setColourScale(ColourScaleType); Chris@1105: ColourScaleType getColourScale() const { return m_colourScale; } Chris@159: Chris@197: void setColourMap(int map); Chris@197: int getColourMap() const; Chris@197: Chris@534: /** Chris@534: * Set the gain multiplier for sample values in this view. Chris@534: * The default is 1.0. Chris@534: */ Chris@534: void setGain(float gain); Chris@534: float getGain() const; Chris@531: Chris@531: /** Chris@531: * Specify the scale for the y axis. Chris@531: */ Chris@1103: void setBinScale(BinScale); Chris@1103: BinScale getBinScale() const; Chris@531: Chris@719: /** Chris@1104: * Specify the normalization mode for individual columns. Chris@719: */ Chris@1104: void setNormalization(ColumnNormalization); Chris@1104: ColumnNormalization getNormalization() const; Chris@1104: Chris@1104: /** Chris@1104: * Specify whether to normalize the visible area. Chris@1104: */ Chris@1104: void setNormalizeVisibleArea(bool); Chris@1104: bool getNormalizeVisibleArea() const; Chris@719: Chris@357: void setInvertVertical(bool i); Chris@357: bool getInvertVertical() const; Chris@357: Chris@465: void setOpaque(bool i); Chris@465: bool getOpaque() const; Chris@465: Chris@535: void setSmooth(bool i); Chris@535: bool getSmooth() const; Chris@535: Chris@1453: bool hasLightBackground() const override; Chris@1453: Chris@1406: bool getValueExtents(double &min, double &max, Chris@1469: bool &logarithmic, QString &unit) const override; Chris@444: Chris@1406: bool getDisplayExtents(double &min, double &max) const override; Chris@1406: bool setDisplayExtents(double min, double max) override; Chris@444: Chris@1406: bool getYScaleValue(const LayerGeometryProvider *, int /* y */, Chris@1469: double &/* value */, QString &/* unit */) const override; Chris@725: Chris@1406: int getVerticalZoomSteps(int &defaultStep) const override; Chris@1406: int getCurrentVerticalZoomStep() const override; Chris@1406: void setVerticalZoomStep(int) override; Chris@1406: RangeMapper *getNewVerticalZoomRangeMapper() const override; Chris@444: Chris@1469: ModelId getSliceableModel() const override { return m_model; } Chris@193: Chris@1406: void toXml(QTextStream &stream, QString indent = "", Chris@1469: QString extraAttributes = "") const override; Chris@197: Chris@0: protected slots: Chris@1481: void handleModelChanged(ModelId); Chris@1481: void handleModelChangedWithin(ModelId, sv_frame_t, sv_frame_t); Chris@0: Chris@0: protected: Chris@1469: ModelId m_model; // A DenseThreeDimensionalModel Chris@0: Chris@1105: ColourScaleType m_colourScale; Chris@1104: bool m_colourScaleSet; Chris@1104: int m_colourMap; Chris@1362: bool m_colourInverted; Chris@1104: float m_gain; Chris@1103: BinScale m_binScale; Chris@1104: ColumnNormalization m_normalization; // of individual columns Chris@1104: bool m_normalizeVisibleArea; Chris@1104: bool m_invertVertical; Chris@1104: bool m_opaque; Chris@1104: bool m_smooth; Chris@1104: int m_peakResolution; Chris@197: Chris@725: // Minimum and maximum bin numbers visible within the view. We Chris@725: // always snap to whole bins at view edges. Chris@1104: int m_miny; Chris@1104: int m_maxy; Chris@1100: Chris@1104: bool m_synchronous; Chris@1104: Chris@1105: static ColourScaleType convertToColourScale(int value); Chris@1105: static int convertFromColourScale(ColourScaleType); Chris@1104: static std::pair convertToColumnNorm(int value); Chris@1104: static int convertFromColumnNorm(ColumnNormalization norm, bool visible); Chris@1101: Chris@1473: mutable ModelId m_peakCache; Chris@1100: const int m_peakCacheDivisor; Chris@1469: void invalidatePeakCache(); Chris@1473: ModelId getPeakCache() const; Chris@1100: Chris@1563: mutable std::vector m_exporters; // used, waiting to be released Chris@1563: Chris@1121: typedef std::map ViewMagMap; // key is view id Chris@1121: mutable ViewMagMap m_viewMags; Chris@1235: mutable ViewMagMap m_lastRenderedMags; // when in normalizeVisibleArea mode Chris@1235: void invalidateMagnitudes(); Chris@1121: Chris@1100: typedef std::map ViewRendererMap; // key is view id Chris@1100: mutable ViewRendererMap m_renderers; Chris@1121: Chris@1113: Colour3DPlotRenderer *getRenderer(const LayerGeometryProvider *) const; Chris@1107: void invalidateRenderers(); Chris@1100: Chris@725: /** Chris@725: * Return the y coordinate at which the given bin "starts" Chris@725: * (i.e. at the bottom of the bin, if the given bin is an integer Chris@725: * and the vertical scale is the usual way up). Bin number may be Chris@725: * fractional, to obtain a position part-way through a bin. Chris@725: */ Chris@1406: double getYForBin(const LayerGeometryProvider *, double bin) const override; Chris@903: Chris@903: /** Chris@725: * Return the bin number, possibly fractional, at the given y Chris@725: * coordinate. Note that the whole numbers occur at the positions Chris@725: * at which the bins "start" (i.e. the bottom of the visible bin, Chris@725: * if the vertical scale is the usual way up). Chris@725: */ Chris@1406: double getBinForY(const LayerGeometryProvider *, double y) const override; Chris@159: Chris@469: int getColourScaleWidth(QPainter &) const; Chris@1101: Chris@1107: void paintWithRenderer(LayerGeometryProvider *v, QPainter &paint, QRect rect) const; Chris@0: }; Chris@0: Chris@0: #endif