Chris@916: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ Chris@916: Chris@916: /* Chris@916: Sonic Visualiser Chris@916: An audio file viewer and annotation editor. Chris@916: Centre for Digital Music, Queen Mary, University of London. Chris@916: Chris@916: This program is free software; you can redistribute it and/or Chris@916: modify it under the terms of the GNU General Public License as Chris@916: published by the Free Software Foundation; either version 2 of the Chris@916: License, or (at your option) any later version. See the file Chris@916: COPYING included with this distribution for more information. Chris@916: */ Chris@916: Chris@1325: #ifndef SV_LAYER_GEOMETRY_PROVIDER_H Chris@1325: #define SV_LAYER_GEOMETRY_PROVIDER_H Chris@916: Chris@916: #include "base/BaseTypes.h" Chris@1325: #include "base/ZoomLevel.h" Chris@916: Chris@1030: #include Chris@1030: #include Chris@1031: #include Chris@1030: Chris@916: class ViewManager; Chris@918: class View; Chris@916: class Layer; Chris@916: Chris@1090: /** Chris@1090: * Interface for classes that provide geometry information (such as Chris@1090: * size, start frame, and a large number of other properties) about Chris@1090: * the disposition of a layer. The main implementor of this interface Chris@1090: * is the View class, but other implementations may be used in Chris@1090: * different circumstances, e.g. as a proxy to handle hi-dpi Chris@1090: * coordinate mapping. Chris@1090: * Chris@1090: * Note it is expected that some implementations of this may be Chris@1090: * disposable, created on-the-fly for a single use. Code that receives Chris@1090: * a LayerGeometryProvider pointer as an argument to something should Chris@1090: * not, in general, store that pointer as it may be invalidated before Chris@1090: * the next use. Use getId() to instead obtain a persistent identifier Chris@1090: * for a LayerGeometryProvider, for example to establish whether the Chris@1090: * same one is being provided in two separate calls. Chris@1090: */ Chris@916: class LayerGeometryProvider Chris@916: { Chris@1044: protected: Chris@1044: static int getNextId() { Chris@1030: static QMutex idMutex; Chris@1030: static int nextId = 1; Chris@1044: static int maxId = INT_MAX; Chris@1030: QMutexLocker locker(&idMutex); Chris@1044: int id = nextId; Chris@1044: if (nextId == maxId) { Chris@1044: // we don't expect this to happen in the lifetime of a Chris@1044: // process, but it would be undefined behaviour if it did Chris@1044: // since we're using a signed int, so we should really Chris@1044: // guard for it... Chris@1044: nextId = 1; Chris@1044: } else { Chris@1044: nextId++; Chris@1044: } Chris@1044: return id; Chris@1044: } Chris@1044: Chris@1044: public: Chris@1044: LayerGeometryProvider() { } Chris@1030: Chris@1030: /** Chris@1044: * Retrieve the id of this object. Chris@1030: */ Chris@1044: virtual int getId() const = 0; Chris@1030: Chris@916: /** Chris@916: * Retrieve the first visible sample frame on the widget. Chris@916: * This is a calculated value based on the centre-frame, widget Chris@916: * width and zoom level. The result may be negative. Chris@916: */ Chris@916: virtual sv_frame_t getStartFrame() const = 0; Chris@916: Chris@916: /** Chris@916: * Return the centre frame of the visible widget. This is an Chris@916: * exact value that does not depend on the zoom block size. Other Chris@916: * frame values (start, end) are calculated from this based on the Chris@916: * zoom and other factors. Chris@916: */ Chris@916: virtual sv_frame_t getCentreFrame() const = 0; Chris@916: Chris@916: /** Chris@916: * Retrieve the last visible sample frame on the widget. Chris@916: * This is a calculated value based on the centre-frame, widget Chris@916: * width and zoom level. Chris@916: */ Chris@916: virtual sv_frame_t getEndFrame() const = 0; Chris@916: Chris@916: /** Chris@916: * Return the pixel x-coordinate corresponding to a given sample Chris@916: * frame (which may be negative). Chris@916: */ Chris@916: virtual int getXForFrame(sv_frame_t frame) const = 0; Chris@916: Chris@916: /** Chris@916: * Return the closest frame to the given pixel x-coordinate. Chris@916: */ Chris@916: virtual sv_frame_t getFrameForX(int x) const = 0; Chris@916: Chris@919: virtual sv_frame_t getModelsStartFrame() const = 0; Chris@919: virtual sv_frame_t getModelsEndFrame() const = 0; Chris@919: Chris@916: /** Chris@1030: * Return the closest pixel x-coordinate corresponding to a given Chris@1030: * view x-coordinate. Chris@1030: */ Chris@1030: virtual int getXForViewX(int viewx) const = 0; Chris@1030: Chris@1030: /** Chris@1030: * Return the closest view x-coordinate corresponding to a given Chris@1030: * pixel x-coordinate. Chris@1030: */ Chris@1030: virtual int getViewXForX(int x) const = 0; Chris@1030: Chris@1030: /** Chris@1085: * Return the (maybe fractional) pixel y-coordinate corresponding Chris@1085: * to a given frequency, if the frequency range is as specified. Chris@1085: * This does not imply any policy about layer frequency ranges, Chris@1085: * but it might be useful for layers to match theirs up if Chris@1085: * desired. Chris@916: * Chris@916: * Not thread-safe in logarithmic mode. Call only from GUI thread. Chris@916: */ Chris@1085: virtual double getYForFrequency(double frequency, Chris@1085: double minFreq, double maxFreq, Chris@916: bool logarithmic) const = 0; Chris@916: Chris@916: /** Chris@1085: * Return the closest frequency to the given (maybe fractional) Chris@1085: * pixel y-coordinate, if the frequency range is as specified. Chris@916: * Chris@916: * Not thread-safe in logarithmic mode. Call only from GUI thread. Chris@916: */ Chris@1085: virtual double getFrequencyForY(double y, Chris@1085: double minFreq, double maxFreq, Chris@1082: bool logarithmic) const = 0; Chris@916: Chris@918: virtual int getTextLabelHeight(const Layer *layer, QPainter &) const = 0; Chris@918: Chris@918: virtual bool getValueExtents(QString unit, double &min, double &max, Chris@918: bool &log) const = 0; Chris@918: Chris@916: /** Chris@1183: * Return the zoom level, i.e. the number of frames per pixel or Chris@1183: * pixels per frame Chris@916: */ Chris@1183: virtual ZoomLevel getZoomLevel() const = 0; Chris@916: Chris@916: /** Chris@916: * To be called from a layer, to obtain the extent of the surface Chris@916: * that the layer is currently painting to. This may be the extent Chris@916: * of the view (if 1x display scaling is in effect) or of a larger Chris@916: * cached pixmap (if greater display scaling is in effect). Chris@916: */ Chris@916: virtual QRect getPaintRect() const = 0; Chris@916: Chris@916: virtual QSize getPaintSize() const { return getPaintRect().size(); } Chris@916: virtual int getPaintWidth() const { return getPaintRect().width(); } Chris@916: virtual int getPaintHeight() const { return getPaintRect().height(); } Chris@916: Chris@916: virtual bool hasLightBackground() const = 0; Chris@916: virtual QColor getForeground() const = 0; Chris@916: virtual QColor getBackground() const = 0; Chris@916: Chris@916: virtual ViewManager *getViewManager() const = 0; Chris@916: Chris@916: virtual bool shouldIlluminateLocalFeatures(const Layer *, QPoint &) const = 0; Chris@919: virtual bool shouldShowFeatureLabels() const = 0; Chris@916: Chris@916: virtual void drawMeasurementRect(QPainter &p, const Layer *, Chris@916: QRect rect, bool focus) const = 0; Chris@916: Chris@1030: virtual void updatePaintRect(QRect r) = 0; Chris@1401: Chris@1401: virtual double scaleSize(double size) const = 0; Chris@1402: virtual int scalePixelSize(int size) const = 0; Chris@1401: virtual double scalePenWidth(double width) const = 0; Chris@1401: virtual QPen scalePen(QPen pen) const = 0; Chris@1030: Chris@918: virtual View *getView() = 0; Chris@918: virtual const View *getView() const = 0; Chris@916: }; Chris@916: Chris@916: #endif