Mercurial > hg > svgui
diff view/ViewProxy.h @ 1490:c83504eb2649
Attempt a mechanism for the View to time-align a layer on display using an aligning version of the ViewProxy
author | Chris Cannam |
---|---|
date | Fri, 02 Aug 2019 16:44:32 +0100 |
parents | a18e78b9c78b |
children | 2f505d843d14 |
line wrap: on
line diff
--- a/view/ViewProxy.h Fri Aug 02 16:42:32 2019 +0100 +++ b/view/ViewProxy.h Fri Aug 02 16:44:32 2019 +0100 @@ -17,33 +17,60 @@ #include "layer/LayerGeometryProvider.h" +#include "data/model/AlignmentModel.h" + class ViewProxy : public LayerGeometryProvider { public: + /** + * Create a standard ViewProxy for the given view, mapping using + * the given scale factor. The scale factor is generally used with + * pixel-doubled "retina" Mac displays and is usually 1 elsewhere. + */ ViewProxy(View *view, int scaleFactor) : m_view(view), m_scaleFactor(scaleFactor) { } + /** + * Create a re-aligning ViewProxy for the given view, mapping + * using the given scale factor. The scale factor is generally + * used with pixel-doubled "retina" Mac displays and is usually 1 + * elsewhere. + * + * Coordinates are mapped through the given alignment model, such + * that frame values passed from the caller are mapped "from + * reference" by that alignment before being used by the view or + * converted to pixel coordinates, and returned values are mapped + * back "to reference" before being passed back to the caller. + * + * This form of proxy may be created specially for rendering a + * single layer which comes from a different alignment to that of + * the rest of the containing view. + */ + ViewProxy(View *view, int scaleFactor, ModelId alignment) : + m_view(view), m_scaleFactor(scaleFactor), m_alignment(alignment) { } + int getId() const override { return m_view->getId(); } sv_frame_t getStartFrame() const override { - return m_view->getStartFrame(); + return alignToReference(m_view->getStartFrame()); } sv_frame_t getCentreFrame() const override { - return m_view->getCentreFrame(); + return alignToReference(m_view->getCentreFrame()); } sv_frame_t getEndFrame() const override { - return m_view->getEndFrame(); + return alignToReference(m_view->getEndFrame()); } int getXForFrame(sv_frame_t frame) const override { //!!! not actually correct, if frame lies between view's pixels - return m_scaleFactor * m_view->getXForFrame(frame); + return m_scaleFactor * m_view->getXForFrame(alignFromReference(frame)); } sv_frame_t getFrameForX(int x) const override { sv_frame_t f0 = m_view->getFrameForX(x / m_scaleFactor); if (m_scaleFactor == 1) return f0; sv_frame_t f1 = m_view->getFrameForX((x / m_scaleFactor) + 1); - return f0 + ((f1 - f0) * (x % m_scaleFactor)) / m_scaleFactor; + sv_frame_t f = f0 + ((f1 - f0) * (x % m_scaleFactor)) / m_scaleFactor; + return alignToReference(f); } int getXForViewX(int viewx) const override { return viewx * m_scaleFactor; @@ -52,10 +79,10 @@ return x / m_scaleFactor; } sv_frame_t getModelsStartFrame() const override { - return m_view->getModelsStartFrame(); + return alignToReference(m_view->getModelsStartFrame()); } sv_frame_t getModelsEndFrame() const override { - return m_view->getModelsEndFrame(); + return alignToReference(m_view->getModelsEndFrame()); } double getYForFrequency(double frequency, double minFreq, double maxFreq, @@ -188,6 +215,23 @@ private: View *m_view; int m_scaleFactor; + ModelId m_alignment; + + sv_frame_t alignToReference(sv_frame_t frame) const { + if (auto am = ModelById::getAs<AlignmentModel>(m_alignment)) { + return am->toReference(frame); + } else { + return frame; + } + } + + sv_frame_t alignFromReference(sv_frame_t frame) const { + if (auto am = ModelById::getAs<AlignmentModel>(m_alignment)) { + return am->fromReference(frame); + } else { + return frame; + } + } }; #endif