Chris@1030
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
Chris@1030
|
2
|
Chris@1030
|
3 /*
|
Chris@1030
|
4 Sonic Visualiser
|
Chris@1030
|
5 An audio file viewer and annotation editor.
|
Chris@1030
|
6 Centre for Digital Music, Queen Mary, University of London.
|
Chris@1030
|
7
|
Chris@1030
|
8 This program is free software; you can redistribute it and/or
|
Chris@1030
|
9 modify it under the terms of the GNU General Public License as
|
Chris@1030
|
10 published by the Free Software Foundation; either version 2 of the
|
Chris@1030
|
11 License, or (at your option) any later version. See the file
|
Chris@1030
|
12 COPYING included with this distribution for more information.
|
Chris@1030
|
13 */
|
Chris@1030
|
14
|
Chris@1030
|
15 #ifndef SCROLLABLE_IMAGE_CACHE_H
|
Chris@1030
|
16 #define SCROLLABLE_IMAGE_CACHE_H
|
Chris@1030
|
17
|
Chris@1030
|
18 #include "base/BaseTypes.h"
|
Chris@1030
|
19
|
Chris@1077
|
20 #include "LayerGeometryProvider.h"
|
Chris@1030
|
21
|
Chris@1030
|
22 #include <QImage>
|
Chris@1030
|
23 #include <QRect>
|
Chris@1030
|
24 #include <QPainter>
|
Chris@1030
|
25
|
Chris@1030
|
26 /**
|
Chris@1030
|
27 * A cached image for a view that scrolls horizontally, primarily the
|
Chris@1030
|
28 * spectrogram. The cache object holds an image, reports the size of
|
Chris@1030
|
29 * the image (likely the same as the underlying view, but it's the
|
Chris@1030
|
30 * caller's responsibility to set the size appropriately), can scroll
|
Chris@1030
|
31 * the image, and can report and update which contiguous horizontal
|
Chris@1030
|
32 * range of the image is valid.
|
Chris@1030
|
33 *
|
Chris@1030
|
34 * The only way to *update* the valid area in a cache is to draw to it
|
Chris@1030
|
35 * using the drawImage call.
|
Chris@1030
|
36 */
|
Chris@1030
|
37 class ScrollableImageCache
|
Chris@1030
|
38 {
|
Chris@1030
|
39 public:
|
Chris@1090
|
40 ScrollableImageCache() :
|
Chris@1030
|
41 m_left(0),
|
Chris@1030
|
42 m_width(0),
|
Chris@1030
|
43 m_startFrame(0),
|
Chris@1030
|
44 m_zoomLevel(0)
|
Chris@1030
|
45 {}
|
Chris@1030
|
46
|
Chris@1030
|
47 void invalidate() {
|
Chris@1030
|
48 m_width = 0;
|
Chris@1030
|
49 }
|
Chris@1030
|
50
|
Chris@1030
|
51 bool isValid() const {
|
Chris@1030
|
52 return m_width > 0;
|
Chris@1030
|
53 }
|
Chris@1030
|
54
|
Chris@1030
|
55 QSize getSize() const {
|
Chris@1030
|
56 return m_image.size();
|
Chris@1030
|
57 }
|
Chris@1030
|
58
|
Chris@1030
|
59 void resize(QSize newSize) {
|
Chris@1079
|
60 if (getSize() != newSize) {
|
Chris@1079
|
61 m_image = QImage(newSize, QImage::Format_ARGB32_Premultiplied);
|
Chris@1079
|
62 invalidate();
|
Chris@1079
|
63 }
|
Chris@1030
|
64 }
|
Chris@1030
|
65
|
Chris@1030
|
66 int getValidLeft() const {
|
Chris@1030
|
67 return m_left;
|
Chris@1030
|
68 }
|
Chris@1030
|
69
|
Chris@1030
|
70 int getValidWidth() const {
|
Chris@1030
|
71 return m_width;
|
Chris@1030
|
72 }
|
Chris@1030
|
73
|
Chris@1030
|
74 int getValidRight() const {
|
Chris@1030
|
75 return m_left + m_width;
|
Chris@1030
|
76 }
|
Chris@1030
|
77
|
Chris@1030
|
78 QRect getValidArea() const {
|
Chris@1030
|
79 return QRect(m_left, 0, m_width, m_image.height());
|
Chris@1030
|
80 }
|
Chris@1030
|
81
|
Chris@1030
|
82 int getZoomLevel() const {
|
Chris@1030
|
83 return m_zoomLevel;
|
Chris@1030
|
84 }
|
Chris@1031
|
85
|
Chris@1031
|
86 void setZoomLevel(int zoom) {
|
Chris@1079
|
87 if (m_zoomLevel != zoom) {
|
Chris@1079
|
88 m_zoomLevel = zoom;
|
Chris@1079
|
89 invalidate();
|
Chris@1079
|
90 }
|
Chris@1031
|
91 }
|
Chris@1030
|
92
|
Chris@1030
|
93 sv_frame_t getStartFrame() const {
|
Chris@1030
|
94 return m_startFrame;
|
Chris@1030
|
95 }
|
Chris@1031
|
96
|
Chris@1031
|
97 /**
|
Chris@1031
|
98 * Set the start frame and invalidate the cache. To scroll,
|
Chris@1031
|
99 * i.e. to set the start frame while retaining cache validity
|
Chris@1031
|
100 * where possible, use scrollTo() instead.
|
Chris@1031
|
101 */
|
Chris@1031
|
102 void setStartFrame(sv_frame_t frame) {
|
Chris@1079
|
103 if (m_startFrame != frame) {
|
Chris@1079
|
104 m_startFrame = frame;
|
Chris@1079
|
105 invalidate();
|
Chris@1079
|
106 }
|
Chris@1030
|
107 }
|
Chris@1030
|
108
|
Chris@1030
|
109 const QImage &getImage() const {
|
Chris@1030
|
110 return m_image;
|
Chris@1030
|
111 }
|
Chris@1030
|
112
|
Chris@1031
|
113 /**
|
Chris@1090
|
114 * Set the new start frame for the cache, according to the
|
Chris@1090
|
115 * geometry of the supplied LayerGeometryProvider, if possible
|
Chris@1090
|
116 * also moving along any existing valid data within the cache so
|
Chris@1090
|
117 * that it continues to be valid for the new start frame.
|
Chris@1031
|
118 */
|
Chris@1113
|
119 void scrollTo(const LayerGeometryProvider *v, sv_frame_t newStartFrame);
|
Chris@1030
|
120
|
Chris@1031
|
121 /**
|
Chris@1031
|
122 * Take a left coordinate and width describing a region, and
|
Chris@1031
|
123 * adjust them so that they are contiguous with the cache valid
|
Chris@1031
|
124 * region and so that the union of the adjusted region with the
|
Chris@1081
|
125 * cache valid region contains the supplied region. Does not
|
Chris@1081
|
126 * modify anything about the cache, only about the arguments.
|
Chris@1031
|
127 */
|
Chris@1031
|
128 void adjustToTouchValidArea(int &left, int &width,
|
Chris@1031
|
129 bool &isLeftOfValidArea) const;
|
Chris@1081
|
130
|
Chris@1031
|
131 /**
|
Chris@1031
|
132 * Draw from an image onto the cache. The supplied image must have
|
Chris@1031
|
133 * the same height as the cache and the full height is always
|
Chris@1031
|
134 * drawn. The left and width parameters determine the target
|
Chris@1031
|
135 * region of the cache, the imageLeft and imageWidth parameters
|
Chris@1031
|
136 * the source region of the image.
|
Chris@1031
|
137 */
|
Chris@1030
|
138 void drawImage(int left,
|
Chris@1030
|
139 int width,
|
Chris@1030
|
140 QImage image,
|
Chris@1030
|
141 int imageLeft,
|
Chris@1031
|
142 int imageWidth);
|
Chris@1030
|
143
|
Chris@1030
|
144 private:
|
Chris@1030
|
145 QImage m_image;
|
Chris@1030
|
146 int m_left; // of valid region
|
Chris@1030
|
147 int m_width; // of valid region
|
Chris@1030
|
148 sv_frame_t m_startFrame;
|
Chris@1030
|
149 int m_zoomLevel;
|
Chris@1030
|
150 };
|
Chris@1030
|
151
|
Chris@1030
|
152 #endif
|