Mercurial > hg > svcore
comparison base/ViewManager.cpp @ 24:bb9291d84810
* Add ffwd/rewind
* Abstract out MultiSelection
author | Chris Cannam |
---|---|
date | Wed, 08 Feb 2006 17:59:16 +0000 |
parents | 742e6882e187 |
children | 4b16526b011b |
comparison
equal
deleted
inserted
replaced
23:6ace4286ba06 | 24:bb9291d84810 |
---|---|
18 | 18 |
19 ViewManager::ViewManager() : | 19 ViewManager::ViewManager() : |
20 m_playSource(0), | 20 m_playSource(0), |
21 m_globalCentreFrame(0), | 21 m_globalCentreFrame(0), |
22 m_globalZoom(1024), | 22 m_globalZoom(1024), |
23 m_playbackFrame(0), | |
23 m_lastLeft(0), | 24 m_lastLeft(0), |
24 m_lastRight(0), | 25 m_lastRight(0), |
25 m_inProgressExclusive(true), | 26 m_inProgressExclusive(true), |
26 m_toolMode(NavigateMode), | 27 m_toolMode(NavigateMode), |
27 m_playLoopMode(false), | 28 m_playLoopMode(false), |
52 std::cout << "ViewManager::getGlobalZoom: returning " << m_globalZoom << std::endl; | 53 std::cout << "ViewManager::getGlobalZoom: returning " << m_globalZoom << std::endl; |
53 #endif | 54 #endif |
54 return m_globalZoom; | 55 return m_globalZoom; |
55 } | 56 } |
56 | 57 |
58 unsigned long | |
59 ViewManager::getPlaybackFrame() const | |
60 { | |
61 if (m_playSource && m_playSource->isPlaying()) { | |
62 m_playbackFrame = m_playSource->getCurrentPlayingFrame(); | |
63 } | |
64 return m_playbackFrame; | |
65 } | |
66 | |
67 void | |
68 ViewManager::setPlaybackFrame(unsigned long f) | |
69 { | |
70 if (m_playbackFrame != f) { | |
71 m_playbackFrame = f; | |
72 if (m_playSource && m_playSource->isPlaying()) { | |
73 m_playSource->play(f); | |
74 } | |
75 emit playbackFrameChanged(f); | |
76 } | |
77 } | |
78 | |
57 bool | 79 bool |
58 ViewManager::haveInProgressSelection() const | 80 ViewManager::haveInProgressSelection() const |
59 { | 81 { |
60 return !m_inProgressSelection.isEmpty(); | 82 return !m_inProgressSelection.isEmpty(); |
61 } | 83 } |
81 { | 103 { |
82 m_inProgressSelection = Selection(); | 104 m_inProgressSelection = Selection(); |
83 emit inProgressSelectionChanged(); | 105 emit inProgressSelectionChanged(); |
84 } | 106 } |
85 | 107 |
86 const ViewManager::SelectionList & | 108 const MultiSelection::SelectionList & |
87 ViewManager::getSelections() const | 109 ViewManager::getSelections() const |
88 { | 110 { |
89 return m_selections; | 111 return m_selections.getSelections(); |
90 } | 112 } |
91 | 113 |
92 void | 114 void |
93 ViewManager::setSelection(const Selection &selection) | 115 ViewManager::setSelection(const Selection &selection) |
94 { | 116 { |
95 clearSelections(); | 117 m_selections.setSelection(selection); |
96 addSelection(selection); | 118 emit selectionChanged(); |
97 } | 119 } |
98 | 120 |
99 void | 121 void |
100 ViewManager::addSelection(const Selection &selection) | 122 ViewManager::addSelection(const Selection &selection) |
101 { | 123 { |
102 m_selections.insert(selection); | 124 m_selections.addSelection(selection); |
103 | |
104 // Cope with a sitation where the new selection overlaps one or | |
105 // more existing ones. This is a terribly inefficient way to do | |
106 // this, but that probably isn't significant in real life. | |
107 | |
108 // It's essential for the correct operation of | |
109 // getContainingSelection that the selections do not overlap, so | |
110 // this is not just a frill. | |
111 | |
112 for (SelectionList::iterator i = m_selections.begin(); | |
113 i != m_selections.end(); ) { | |
114 | |
115 SelectionList::iterator j = i; | |
116 if (++j == m_selections.end()) break; | |
117 | |
118 if (i->getEndFrame() >= j->getStartFrame()) { | |
119 Selection merged(i->getStartFrame(), | |
120 std::max(i->getEndFrame(), j->getEndFrame())); | |
121 m_selections.erase(i); | |
122 m_selections.erase(j); | |
123 m_selections.insert(merged); | |
124 i = m_selections.begin(); | |
125 } else { | |
126 ++i; | |
127 } | |
128 } | |
129 | |
130 emit selectionChanged(); | 125 emit selectionChanged(); |
131 } | 126 } |
132 | 127 |
133 void | 128 void |
134 ViewManager::removeSelection(const Selection &selection) | 129 ViewManager::removeSelection(const Selection &selection) |
135 { | 130 { |
136 //!!! Likewise this needs to cope correctly with the situation | 131 m_selections.removeSelection(selection); |
137 //where selection is not one of the original selection set but | 132 emit selectionChanged(); |
138 //simply overlaps one of them (cutting down the original selection | |
139 //appropriately) | |
140 | |
141 if (m_selections.find(selection) != m_selections.end()) { | |
142 m_selections.erase(selection); | |
143 emit selectionChanged(); | |
144 } | |
145 } | 133 } |
146 | 134 |
147 void | 135 void |
148 ViewManager::clearSelections() | 136 ViewManager::clearSelections() |
149 { | 137 { |
150 if (!m_selections.empty()) { | 138 m_selections.clearSelections(); |
151 m_selections.clear(); | 139 emit selectionChanged(); |
152 emit selectionChanged(); | |
153 } | |
154 } | 140 } |
155 | 141 |
156 Selection | 142 Selection |
157 ViewManager::getContainingSelection(size_t frame, bool defaultToFollowing) | 143 ViewManager::getContainingSelection(size_t frame, bool defaultToFollowing) |
158 { | 144 { |
159 // This scales very badly with the number of selections, but it's | 145 return m_selections.getContainingSelection(frame, defaultToFollowing); |
160 // more efficient for very small numbers of selections than a more | |
161 // scalable method, and I think that may be what we need | |
162 | |
163 for (SelectionList::const_iterator i = m_selections.begin(); | |
164 i != m_selections.end(); ++i) { | |
165 | |
166 if (i->contains(frame)) return *i; | |
167 | |
168 if (i->getStartFrame() > frame) { | |
169 if (defaultToFollowing) return *i; | |
170 else return Selection(); | |
171 } | |
172 } | |
173 | |
174 return Selection(); | |
175 } | 146 } |
176 | 147 |
177 void | 148 void |
178 ViewManager::setToolMode(ToolMode mode) | 149 ViewManager::setToolMode(ToolMode mode) |
179 { | 150 { |
245 m_lastLeft = left; | 216 m_lastLeft = left; |
246 m_lastRight = right; | 217 m_lastRight = right; |
247 } | 218 } |
248 } | 219 } |
249 | 220 |
250 m_globalCentreFrame = m_playSource->getCurrentPlayingFrame(); | 221 m_playbackFrame = m_playSource->getCurrentPlayingFrame(); |
251 | 222 |
252 #ifdef DEBUG_VIEW_MANAGER | 223 #ifdef DEBUG_VIEW_MANAGER |
253 std::cout << "ViewManager::checkPlayStatus: Playing, frame " << m_globalCentreFrame << ", levels " << m_lastLeft << "," << m_lastRight << std::endl; | 224 std::cout << "ViewManager::checkPlayStatus: Playing, frame " << m_playbackFrame << ", levels " << m_lastLeft << "," << m_lastRight << std::endl; |
254 #endif | 225 #endif |
255 | 226 |
256 emit playbackFrameChanged(m_globalCentreFrame); | 227 emit playbackFrameChanged(m_playbackFrame); |
257 | 228 |
258 QTimer::singleShot(20, this, SLOT(checkPlayStatus())); | 229 QTimer::singleShot(20, this, SLOT(checkPlayStatus())); |
259 | 230 |
260 } else { | 231 } else { |
261 | 232 |
294 | 265 |
295 if (m_playSource && m_playSource->isPlaying()) { | 266 if (m_playSource && m_playSource->isPlaying()) { |
296 unsigned long playFrame = m_playSource->getCurrentPlayingFrame(); | 267 unsigned long playFrame = m_playSource->getCurrentPlayingFrame(); |
297 unsigned long diff = std::max(f, playFrame) - std::min(f, playFrame); | 268 unsigned long diff = std::max(f, playFrame) - std::min(f, playFrame); |
298 if (diff > 20000) { | 269 if (diff > 20000) { |
270 m_playbackFrame = f; | |
299 m_playSource->play(f); | 271 m_playSource->play(f); |
300 #ifdef DEBUG_VIEW_MANAGER | 272 #ifdef DEBUG_VIEW_MANAGER |
301 std::cout << "ViewManager::considerSeek: reseeking from " << playFrame << " to " << f << std::endl; | 273 std::cout << "ViewManager::considerSeek: reseeking from " << playFrame << " to " << f << std::endl; |
302 #endif | 274 #endif |
303 } | 275 } |
276 } else { | |
277 m_playbackFrame = f; //!!! only if that view is in scroll mode? | |
304 } | 278 } |
305 } | 279 } |
306 | 280 |
307 void | 281 void |
308 ViewManager::considerZoomChange(void *p, unsigned long z, bool locked) | 282 ViewManager::considerZoomChange(void *p, unsigned long z, bool locked) |