annotate layer/LayerGeometryProvider.h @ 1548:bd6af89982d7

Permit getScaleProvidingLayerForUnit to return a dormant layer if there is no visible alternative. This is necessary to avoid the scale disappearing in Tony when the spectrogram is toggled off.
author Chris Cannam
date Thu, 17 Oct 2019 14:44:22 +0100
parents 4f8c72adbf43
children
rev   line source
Chris@916 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@916 2
Chris@916 3 /*
Chris@916 4 Sonic Visualiser
Chris@916 5 An audio file viewer and annotation editor.
Chris@916 6 Centre for Digital Music, Queen Mary, University of London.
Chris@916 7
Chris@916 8 This program is free software; you can redistribute it and/or
Chris@916 9 modify it under the terms of the GNU General Public License as
Chris@916 10 published by the Free Software Foundation; either version 2 of the
Chris@916 11 License, or (at your option) any later version. See the file
Chris@916 12 COPYING included with this distribution for more information.
Chris@916 13 */
Chris@916 14
Chris@1325 15 #ifndef SV_LAYER_GEOMETRY_PROVIDER_H
Chris@1325 16 #define SV_LAYER_GEOMETRY_PROVIDER_H
Chris@916 17
Chris@916 18 #include "base/BaseTypes.h"
Chris@1325 19 #include "base/ZoomLevel.h"
Chris@916 20
Chris@1030 21 #include <QMutex>
Chris@1030 22 #include <QMutexLocker>
Chris@1031 23 #include <QPainter>
Chris@1030 24
Chris@916 25 class ViewManager;
Chris@918 26 class View;
Chris@916 27 class Layer;
Chris@916 28
Chris@1090 29 /**
Chris@1090 30 * Interface for classes that provide geometry information (such as
Chris@1090 31 * size, start frame, and a large number of other properties) about
Chris@1090 32 * the disposition of a layer. The main implementor of this interface
Chris@1090 33 * is the View class, but other implementations may be used in
Chris@1090 34 * different circumstances, e.g. as a proxy to handle hi-dpi
Chris@1090 35 * coordinate mapping.
Chris@1090 36 *
Chris@1090 37 * Note it is expected that some implementations of this may be
Chris@1090 38 * disposable, created on-the-fly for a single use. Code that receives
Chris@1090 39 * a LayerGeometryProvider pointer as an argument to something should
Chris@1090 40 * not, in general, store that pointer as it may be invalidated before
Chris@1090 41 * the next use. Use getId() to instead obtain a persistent identifier
Chris@1090 42 * for a LayerGeometryProvider, for example to establish whether the
Chris@1090 43 * same one is being provided in two separate calls.
Chris@1090 44 */
Chris@916 45 class LayerGeometryProvider
Chris@916 46 {
Chris@1044 47 protected:
Chris@1044 48 static int getNextId() {
Chris@1030 49 static QMutex idMutex;
Chris@1030 50 static int nextId = 1;
Chris@1044 51 static int maxId = INT_MAX;
Chris@1030 52 QMutexLocker locker(&idMutex);
Chris@1044 53 int id = nextId;
Chris@1044 54 if (nextId == maxId) {
Chris@1044 55 // we don't expect this to happen in the lifetime of a
Chris@1044 56 // process, but it would be undefined behaviour if it did
Chris@1044 57 // since we're using a signed int, so we should really
Chris@1044 58 // guard for it...
Chris@1044 59 nextId = 1;
Chris@1044 60 } else {
Chris@1044 61 nextId++;
Chris@1044 62 }
Chris@1044 63 return id;
Chris@1044 64 }
Chris@1044 65
Chris@1044 66 public:
Chris@1044 67 LayerGeometryProvider() { }
Chris@1030 68
Chris@1030 69 /**
Chris@1044 70 * Retrieve the id of this object.
Chris@1030 71 */
Chris@1044 72 virtual int getId() const = 0;
Chris@1030 73
Chris@916 74 /**
Chris@916 75 * Retrieve the first visible sample frame on the widget.
Chris@916 76 * This is a calculated value based on the centre-frame, widget
Chris@916 77 * width and zoom level. The result may be negative.
Chris@916 78 */
Chris@916 79 virtual sv_frame_t getStartFrame() const = 0;
Chris@916 80
Chris@916 81 /**
Chris@916 82 * Return the centre frame of the visible widget. This is an
Chris@916 83 * exact value that does not depend on the zoom block size. Other
Chris@916 84 * frame values (start, end) are calculated from this based on the
Chris@916 85 * zoom and other factors.
Chris@916 86 */
Chris@916 87 virtual sv_frame_t getCentreFrame() const = 0;
Chris@916 88
Chris@916 89 /**
Chris@916 90 * Retrieve the last visible sample frame on the widget.
Chris@916 91 * This is a calculated value based on the centre-frame, widget
Chris@916 92 * width and zoom level.
Chris@916 93 */
Chris@916 94 virtual sv_frame_t getEndFrame() const = 0;
Chris@916 95
Chris@916 96 /**
Chris@916 97 * Return the pixel x-coordinate corresponding to a given sample
Chris@916 98 * frame (which may be negative).
Chris@916 99 */
Chris@916 100 virtual int getXForFrame(sv_frame_t frame) const = 0;
Chris@916 101
Chris@916 102 /**
Chris@916 103 * Return the closest frame to the given pixel x-coordinate.
Chris@916 104 */
Chris@916 105 virtual sv_frame_t getFrameForX(int x) const = 0;
Chris@916 106
Chris@919 107 virtual sv_frame_t getModelsStartFrame() const = 0;
Chris@919 108 virtual sv_frame_t getModelsEndFrame() const = 0;
Chris@919 109
Chris@916 110 /**
Chris@1030 111 * Return the closest pixel x-coordinate corresponding to a given
Chris@1030 112 * view x-coordinate.
Chris@1030 113 */
Chris@1030 114 virtual int getXForViewX(int viewx) const = 0;
Chris@1030 115
Chris@1030 116 /**
Chris@1030 117 * Return the closest view x-coordinate corresponding to a given
Chris@1030 118 * pixel x-coordinate.
Chris@1030 119 */
Chris@1030 120 virtual int getViewXForX(int x) const = 0;
Chris@1030 121
Chris@1030 122 /**
Chris@1085 123 * Return the (maybe fractional) pixel y-coordinate corresponding
Chris@1085 124 * to a given frequency, if the frequency range is as specified.
Chris@1085 125 * This does not imply any policy about layer frequency ranges,
Chris@1085 126 * but it might be useful for layers to match theirs up if
Chris@1085 127 * desired.
Chris@916 128 *
Chris@916 129 * Not thread-safe in logarithmic mode. Call only from GUI thread.
Chris@916 130 */
Chris@1085 131 virtual double getYForFrequency(double frequency,
Chris@1085 132 double minFreq, double maxFreq,
Chris@916 133 bool logarithmic) const = 0;
Chris@916 134
Chris@916 135 /**
Chris@1085 136 * Return the closest frequency to the given (maybe fractional)
Chris@1085 137 * pixel y-coordinate, if the frequency range is as specified.
Chris@916 138 *
Chris@916 139 * Not thread-safe in logarithmic mode. Call only from GUI thread.
Chris@916 140 */
Chris@1085 141 virtual double getFrequencyForY(double y,
Chris@1085 142 double minFreq, double maxFreq,
Chris@1082 143 bool logarithmic) const = 0;
Chris@916 144
Chris@1537 145 /**
Chris@1537 146 * Return a y-coordinate at which text labels for individual items
Chris@1537 147 * in a layer may be drawn, so as not to overlap with those of
Chris@1537 148 * other layers. The returned coordinate will be near the top of
Chris@1537 149 * the visible widget, but adjusted downward depending on how many
Chris@1537 150 * other visible layers return true from their implementation of
Chris@1537 151 * Layer::needsTextLabelHeight().
Chris@1537 152 */
Chris@1537 153 virtual int getTextLabelYCoord(const Layer *layer, QPainter &) const = 0;
Chris@918 154
Chris@1537 155 /**
Chris@1537 156 * Return the visible vertical extents for the given unit, if any.
Chris@1537 157 * That is:
Chris@1537 158 *
Chris@1537 159 * - if at least one non-dormant layer uses the same unit and
Chris@1537 160 * returns some values from its getDisplayExtents() method,
Chris@1537 161 * return the extents from the topmost of those
Chris@1537 162 *
Chris@1537 163 * - otherwise, if at least one non-dormant layer uses the same
Chris@1537 164 * unit, return the union of the value extents of all of those
Chris@1537 165 *
Chris@1537 166 * - otherwise return false
Chris@1537 167 */
Chris@1537 168 virtual bool getVisibleExtentsForUnit(QString unit,
Chris@1537 169 double &min, double &max,
Chris@1537 170 bool &log) const = 0;
Chris@918 171
Chris@916 172 /**
Chris@1183 173 * Return the zoom level, i.e. the number of frames per pixel or
Chris@1183 174 * pixels per frame
Chris@916 175 */
Chris@1183 176 virtual ZoomLevel getZoomLevel() const = 0;
Chris@916 177
Chris@916 178 /**
Chris@916 179 * To be called from a layer, to obtain the extent of the surface
Chris@916 180 * that the layer is currently painting to. This may be the extent
Chris@916 181 * of the view (if 1x display scaling is in effect) or of a larger
Chris@916 182 * cached pixmap (if greater display scaling is in effect).
Chris@916 183 */
Chris@916 184 virtual QRect getPaintRect() const = 0;
Chris@916 185
Chris@916 186 virtual QSize getPaintSize() const { return getPaintRect().size(); }
Chris@916 187 virtual int getPaintWidth() const { return getPaintRect().width(); }
Chris@916 188 virtual int getPaintHeight() const { return getPaintRect().height(); }
Chris@916 189
Chris@916 190 virtual bool hasLightBackground() const = 0;
Chris@916 191 virtual QColor getForeground() const = 0;
Chris@916 192 virtual QColor getBackground() const = 0;
Chris@916 193
Chris@916 194 virtual ViewManager *getViewManager() const = 0;
Chris@916 195
Chris@916 196 virtual bool shouldIlluminateLocalFeatures(const Layer *, QPoint &) const = 0;
Chris@919 197 virtual bool shouldShowFeatureLabels() const = 0;
Chris@916 198
Chris@916 199 virtual void drawMeasurementRect(QPainter &p, const Layer *,
Chris@916 200 QRect rect, bool focus) const = 0;
Chris@916 201
Chris@1030 202 virtual void updatePaintRect(QRect r) = 0;
Chris@1401 203
Chris@1401 204 virtual double scaleSize(double size) const = 0;
Chris@1402 205 virtual int scalePixelSize(int size) const = 0;
Chris@1401 206 virtual double scalePenWidth(double width) const = 0;
Chris@1401 207 virtual QPen scalePen(QPen pen) const = 0;
Chris@1030 208
Chris@918 209 virtual View *getView() = 0;
Chris@918 210 virtual const View *getView() const = 0;
Chris@916 211 };
Chris@916 212
Chris@916 213 #endif