comparison 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
comparison
equal deleted inserted replaced
1489:b402121d8f5f 1490:c83504eb2649
15 #ifndef VIEW_PROXY_H 15 #ifndef VIEW_PROXY_H
16 #define VIEW_PROXY_H 16 #define VIEW_PROXY_H
17 17
18 #include "layer/LayerGeometryProvider.h" 18 #include "layer/LayerGeometryProvider.h"
19 19
20 #include "data/model/AlignmentModel.h"
21
20 class ViewProxy : public LayerGeometryProvider 22 class ViewProxy : public LayerGeometryProvider
21 { 23 {
22 public: 24 public:
25 /**
26 * Create a standard ViewProxy for the given view, mapping using
27 * the given scale factor. The scale factor is generally used with
28 * pixel-doubled "retina" Mac displays and is usually 1 elsewhere.
29 */
23 ViewProxy(View *view, int scaleFactor) : 30 ViewProxy(View *view, int scaleFactor) :
24 m_view(view), m_scaleFactor(scaleFactor) { } 31 m_view(view), m_scaleFactor(scaleFactor) { }
25 32
33 /**
34 * Create a re-aligning ViewProxy for the given view, mapping
35 * using the given scale factor. The scale factor is generally
36 * used with pixel-doubled "retina" Mac displays and is usually 1
37 * elsewhere.
38 *
39 * Coordinates are mapped through the given alignment model, such
40 * that frame values passed from the caller are mapped "from
41 * reference" by that alignment before being used by the view or
42 * converted to pixel coordinates, and returned values are mapped
43 * back "to reference" before being passed back to the caller.
44 *
45 * This form of proxy may be created specially for rendering a
46 * single layer which comes from a different alignment to that of
47 * the rest of the containing view.
48 */
49 ViewProxy(View *view, int scaleFactor, ModelId alignment) :
50 m_view(view), m_scaleFactor(scaleFactor), m_alignment(alignment) { }
51
26 int getId() const override { 52 int getId() const override {
27 return m_view->getId(); 53 return m_view->getId();
28 } 54 }
29 sv_frame_t getStartFrame() const override { 55 sv_frame_t getStartFrame() const override {
30 return m_view->getStartFrame(); 56 return alignToReference(m_view->getStartFrame());
31 } 57 }
32 sv_frame_t getCentreFrame() const override { 58 sv_frame_t getCentreFrame() const override {
33 return m_view->getCentreFrame(); 59 return alignToReference(m_view->getCentreFrame());
34 } 60 }
35 sv_frame_t getEndFrame() const override { 61 sv_frame_t getEndFrame() const override {
36 return m_view->getEndFrame(); 62 return alignToReference(m_view->getEndFrame());
37 } 63 }
38 int getXForFrame(sv_frame_t frame) const override { 64 int getXForFrame(sv_frame_t frame) const override {
39 //!!! not actually correct, if frame lies between view's pixels 65 //!!! not actually correct, if frame lies between view's pixels
40 return m_scaleFactor * m_view->getXForFrame(frame); 66 return m_scaleFactor * m_view->getXForFrame(alignFromReference(frame));
41 } 67 }
42 sv_frame_t getFrameForX(int x) const override { 68 sv_frame_t getFrameForX(int x) const override {
43 sv_frame_t f0 = m_view->getFrameForX(x / m_scaleFactor); 69 sv_frame_t f0 = m_view->getFrameForX(x / m_scaleFactor);
44 if (m_scaleFactor == 1) return f0; 70 if (m_scaleFactor == 1) return f0;
45 sv_frame_t f1 = m_view->getFrameForX((x / m_scaleFactor) + 1); 71 sv_frame_t f1 = m_view->getFrameForX((x / m_scaleFactor) + 1);
46 return f0 + ((f1 - f0) * (x % m_scaleFactor)) / m_scaleFactor; 72 sv_frame_t f = f0 + ((f1 - f0) * (x % m_scaleFactor)) / m_scaleFactor;
73 return alignToReference(f);
47 } 74 }
48 int getXForViewX(int viewx) const override { 75 int getXForViewX(int viewx) const override {
49 return viewx * m_scaleFactor; 76 return viewx * m_scaleFactor;
50 } 77 }
51 int getViewXForX(int x) const override { 78 int getViewXForX(int x) const override {
52 return x / m_scaleFactor; 79 return x / m_scaleFactor;
53 } 80 }
54 sv_frame_t getModelsStartFrame() const override { 81 sv_frame_t getModelsStartFrame() const override {
55 return m_view->getModelsStartFrame(); 82 return alignToReference(m_view->getModelsStartFrame());
56 } 83 }
57 sv_frame_t getModelsEndFrame() const override { 84 sv_frame_t getModelsEndFrame() const override {
58 return m_view->getModelsEndFrame(); 85 return alignToReference(m_view->getModelsEndFrame());
59 } 86 }
60 double getYForFrequency(double frequency, 87 double getYForFrequency(double frequency,
61 double minFreq, double maxFreq, 88 double minFreq, double maxFreq,
62 bool logarithmic) const override { 89 bool logarithmic) const override {
63 return m_scaleFactor * 90 return m_scaleFactor *
186 const View *getView() const override { return m_view; } 213 const View *getView() const override { return m_view; }
187 214
188 private: 215 private:
189 View *m_view; 216 View *m_view;
190 int m_scaleFactor; 217 int m_scaleFactor;
218 ModelId m_alignment;
219
220 sv_frame_t alignToReference(sv_frame_t frame) const {
221 if (auto am = ModelById::getAs<AlignmentModel>(m_alignment)) {
222 return am->toReference(frame);
223 } else {
224 return frame;
225 }
226 }
227
228 sv_frame_t alignFromReference(sv_frame_t frame) const {
229 if (auto am = ModelById::getAs<AlignmentModel>(m_alignment)) {
230 return am->fromReference(frame);
231 } else {
232 return frame;
233 }
234 }
191 }; 235 };
192 236
193 #endif 237 #endif