annotate base/ZoomLevel.h @ 1879:652c5360e682

Ensure transforms are populated before instantiateDefaultPluginFor runs - otherwise if we have prior knowledge of a transform id, we can find ourselves trying to instantiate it before the plugin factory has heard of it and e.g. knows which server to use
author Chris Cannam
date Thu, 25 Jun 2020 12:20:06 +0100
parents 8f9e9cff141d
children 1ae6a19464a7
rev   line source
Chris@1532 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@1532 2
Chris@1532 3 /*
Chris@1532 4 Sonic Visualiser
Chris@1532 5 An audio file viewer and annotation editor.
Chris@1532 6 Centre for Digital Music, Queen Mary, University of London.
Chris@1532 7
Chris@1532 8 This program is free software; you can redistribute it and/or
Chris@1532 9 modify it under the terms of the GNU General Public License as
Chris@1532 10 published by the Free Software Foundation; either version 2 of the
Chris@1532 11 License, or (at your option) any later version. See the file
Chris@1532 12 COPYING included with this distribution for more information.
Chris@1532 13 */
Chris@1532 14
Chris@1532 15 #ifndef SV_ZOOM_LEVEL_H
Chris@1532 16 #define SV_ZOOM_LEVEL_H
Chris@1532 17
Chris@1534 18 #include "BaseTypes.h"
Chris@1534 19
Chris@1532 20 #include <ostream>
Chris@1533 21 #include <cmath>
Chris@1532 22
Chris@1532 23 /** Display zoom level. Can be an integer number of samples per pixel,
Chris@1532 24 * or an integer number of pixels per sample.
Chris@1532 25 */
Chris@1532 26 struct ZoomLevel {
Chris@1532 27
Chris@1532 28 enum Zone {
Chris@1532 29 FramesPerPixel, // zoomed out (as in classic SV)
Chris@1532 30 PixelsPerFrame // zoomed in beyond 1-1 (interpolating the waveform)
Chris@1532 31 };
Chris@1533 32
Chris@1532 33 Zone zone;
Chris@1532 34 int level;
Chris@1532 35
Chris@1532 36 ZoomLevel() : zone(FramesPerPixel), level(1) { }
Chris@1532 37 ZoomLevel(Zone z, int lev) : zone(z), level(lev) { }
Chris@1532 38
Chris@1532 39 bool operator<(const ZoomLevel &other) const {
Chris@1532 40 if (zone == FramesPerPixel) {
Chris@1532 41 if (other.zone == zone) {
Chris@1532 42 return level < other.level;
Chris@1532 43 } else {
Chris@1532 44 return false;
Chris@1532 45 }
Chris@1532 46 } else {
Chris@1532 47 if (other.zone == zone) {
Chris@1532 48 return level > other.level;
Chris@1532 49 } else {
Chris@1532 50 return false;
Chris@1532 51 }
Chris@1532 52 }
Chris@1532 53 }
Chris@1532 54
Chris@1532 55 bool operator==(const ZoomLevel &other) const {
Chris@1532 56 return (zone == other.zone && level == other.level);
Chris@1532 57 }
Chris@1532 58
Chris@1532 59 ZoomLevel incremented() const {
Chris@1532 60 if (zone == FramesPerPixel) {
Chris@1532 61 return { zone, level + 1 };
Chris@1532 62 } else if (level == 1) {
Chris@1532 63 return { FramesPerPixel, 2 };
Chris@1532 64 } else if (level == 2) {
Chris@1532 65 return { FramesPerPixel, 1 };
Chris@1532 66 } else {
Chris@1532 67 return { zone, level - 1 };
Chris@1532 68 }
Chris@1532 69 }
Chris@1532 70
Chris@1532 71 ZoomLevel decremented() const {
Chris@1532 72 if (zone == PixelsPerFrame) {
Chris@1532 73 return { zone, level + 1 };
Chris@1532 74 } else if (level == 1) {
Chris@1532 75 return { PixelsPerFrame, 2 };
Chris@1532 76 } else {
Chris@1532 77 return { zone, level - 1 };
Chris@1532 78 }
Chris@1532 79 }
Chris@1532 80
Chris@1533 81 /** Inexact conversion. The result is a whole number if we are
Chris@1533 82 * zoomed in enough (in PixelsPerFrame zone), a fraction
Chris@1533 83 * otherwise.
Chris@1533 84 */
Chris@1532 85 double framesToPixels(double frames) const {
Chris@1532 86 if (zone == PixelsPerFrame) {
Chris@1532 87 return frames * level;
Chris@1532 88 } else {
Chris@1532 89 return frames / level;
Chris@1532 90 }
Chris@1532 91 }
Chris@1532 92
Chris@1533 93 /** Inexact conversion. The result is a whole number if we are
Chris@1533 94 * zoomed out enough (in FramesPerPixel zone), a fraction
Chris@1533 95 * otherwise.
Chris@1533 96 */
Chris@1532 97 double pixelsToFrames(double pixels) const {
Chris@1532 98 if (zone == PixelsPerFrame) {
Chris@1532 99 return pixels / level;
Chris@1532 100 } else {
Chris@1532 101 return pixels * level;
Chris@1532 102 }
Chris@1532 103 }
Chris@1533 104
Chris@1533 105 /** Return a ZoomLevel that approximates the given ratio of pixels
Chris@1533 106 * to frames.
Chris@1533 107 */
Chris@1534 108 static ZoomLevel fromRatio(int pixels, sv_frame_t frames) {
Chris@1533 109 if (pixels < frames) {
Chris@1534 110 return { FramesPerPixel, int(round(double(frames)/pixels)) };
Chris@1533 111 } else {
Chris@1534 112 int r = int(round(pixels/double(frames)));
Chris@1533 113 if (r > 1) {
Chris@1533 114 return { PixelsPerFrame, r };
Chris@1533 115 } else {
Chris@1533 116 return { FramesPerPixel, 1 };
Chris@1533 117 }
Chris@1533 118 }
Chris@1533 119 }
Chris@1532 120 };
Chris@1532 121
Chris@1532 122 std::ostream &operator<<(std::ostream &s, const ZoomLevel &z);
Chris@1532 123
Chris@1532 124 #endif