annotate base/ViewManager.cpp @ 8:214054a0d8b8

* Hook up tool selection buttons to switch the cursor mode * Implement simple and multi-selection, snapping to the resolution of the current layer. You can't actually do anything with a selection yet
author Chris Cannam
date Mon, 23 Jan 2006 17:02:57 +0000
parents d86891498eef
children 73d85d19919f
rev   line source
Chris@0 1 /* -*- c-basic-offset: 4 -*- vi:set ts=8 sts=4 sw=4: */
Chris@0 2
Chris@0 3 /*
Chris@0 4 A waveform viewer and audio annotation editor.
Chris@2 5 Chris Cannam, Queen Mary University of London, 2005-2006
Chris@0 6
Chris@0 7 This is experimental software. Not for distribution.
Chris@0 8 */
Chris@0 9
Chris@0 10 #include "ViewManager.h"
Chris@0 11 #include "AudioPlaySource.h"
Chris@0 12 #include "PlayParameters.h"
Chris@0 13 #include "Model.h"
Chris@0 14
Chris@0 15 #include <iostream>
Chris@0 16
Chris@0 17 //#define DEBUG_VIEW_MANAGER 1
Chris@0 18
Chris@0 19 ViewManager::ViewManager() :
Chris@0 20 m_playSource(0),
Chris@0 21 m_globalCentreFrame(0),
Chris@0 22 m_globalZoom(1024),
Chris@0 23 m_lastLeft(0),
Chris@8 24 m_lastRight(0),
Chris@8 25 m_inProgressExclusive(true),
Chris@8 26 m_toolMode(NavigateMode)
Chris@0 27 {
Chris@0 28 connect(this,
Chris@0 29 SIGNAL(centreFrameChanged(void *, unsigned long, bool)),
Chris@0 30 SLOT(considerSeek(void *, unsigned long, bool)));
Chris@0 31
Chris@0 32 connect(this,
Chris@0 33 SIGNAL(zoomLevelChanged(void *, unsigned long, bool)),
Chris@0 34 SLOT(considerZoomChange(void *, unsigned long, bool)));
Chris@0 35 }
Chris@0 36
Chris@0 37 unsigned long
Chris@0 38 ViewManager::getGlobalCentreFrame() const
Chris@0 39 {
Chris@0 40 #ifdef DEBUG_VIEW_MANAGER
Chris@0 41 std::cout << "ViewManager::getGlobalCentreFrame: returning " << m_globalCentreFrame << std::endl;
Chris@0 42 #endif
Chris@0 43 return m_globalCentreFrame;
Chris@0 44 }
Chris@0 45
Chris@0 46 unsigned long
Chris@0 47 ViewManager::getGlobalZoom() const
Chris@0 48 {
Chris@0 49 #ifdef DEBUG_VIEW_MANAGER
Chris@0 50 std::cout << "ViewManager::getGlobalZoom: returning " << m_globalZoom << std::endl;
Chris@0 51 #endif
Chris@0 52 return m_globalZoom;
Chris@0 53 }
Chris@0 54
Chris@8 55 bool
Chris@8 56 ViewManager::haveInProgressSelection() const
Chris@8 57 {
Chris@8 58 return !m_inProgressSelection.isEmpty();
Chris@8 59 }
Chris@8 60
Chris@8 61 const Selection &
Chris@8 62 ViewManager::getInProgressSelection(bool &exclusive) const
Chris@8 63 {
Chris@8 64 exclusive = m_inProgressExclusive;
Chris@8 65 return m_inProgressSelection;
Chris@8 66 }
Chris@8 67
Chris@8 68 void
Chris@8 69 ViewManager::setInProgressSelection(const Selection &selection, bool exclusive)
Chris@8 70 {
Chris@8 71 m_inProgressExclusive = exclusive;
Chris@8 72 m_inProgressSelection = selection;
Chris@8 73 if (exclusive) clearSelections();
Chris@8 74 emit selectionChanged();
Chris@8 75 }
Chris@8 76
Chris@8 77 void
Chris@8 78 ViewManager::clearInProgressSelection()
Chris@8 79 {
Chris@8 80 m_inProgressSelection = Selection();
Chris@8 81 emit selectionChanged();
Chris@8 82 }
Chris@8 83
Chris@8 84 const ViewManager::SelectionList &
Chris@8 85 ViewManager::getSelections() const
Chris@8 86 {
Chris@8 87 return m_selections;
Chris@8 88 }
Chris@8 89
Chris@8 90 void
Chris@8 91 ViewManager::setSelection(const Selection &selection)
Chris@8 92 {
Chris@8 93 clearSelections();
Chris@8 94 addSelection(selection);
Chris@8 95 }
Chris@8 96
Chris@8 97 void
Chris@8 98 ViewManager::addSelection(const Selection &selection)
Chris@8 99 {
Chris@8 100 m_selections.insert(selection);
Chris@8 101
Chris@8 102 // Cope with a sitation where the new selection overlaps one or
Chris@8 103 // more existing ones. This is a terribly inefficient way to do
Chris@8 104 // this, but that probably isn't significant in real life.
Chris@8 105
Chris@8 106 for (SelectionList::iterator i = m_selections.begin();
Chris@8 107 i != m_selections.end(); ) {
Chris@8 108
Chris@8 109 SelectionList::iterator j = i;
Chris@8 110 if (++j == m_selections.end()) break;
Chris@8 111
Chris@8 112 if (i->getEndFrame() >= j->getStartFrame()) {
Chris@8 113 Selection merged(i->getStartFrame(),
Chris@8 114 std::max(i->getEndFrame(), j->getEndFrame()));
Chris@8 115 m_selections.erase(i);
Chris@8 116 m_selections.erase(j);
Chris@8 117 m_selections.insert(merged);
Chris@8 118 i = m_selections.begin();
Chris@8 119 } else {
Chris@8 120 ++i;
Chris@8 121 }
Chris@8 122 }
Chris@8 123
Chris@8 124 emit selectionChanged();
Chris@8 125 }
Chris@8 126
Chris@8 127 void
Chris@8 128 ViewManager::removeSelection(const Selection &selection)
Chris@8 129 {
Chris@8 130 //!!! Likewise this needs to cope correctly with the situation
Chris@8 131 //where selection is not one of the original selection set but
Chris@8 132 //simply overlaps one of them (cutting down the original selection
Chris@8 133 //appropriately)
Chris@8 134
Chris@8 135 m_selections.erase(selection);
Chris@8 136
Chris@8 137 emit selectionChanged();
Chris@8 138 }
Chris@8 139
Chris@8 140 void
Chris@8 141 ViewManager::clearSelections()
Chris@8 142 {
Chris@8 143 m_selections.clear();
Chris@8 144
Chris@8 145 emit selectionChanged();
Chris@8 146 }
Chris@8 147
Chris@8 148 void
Chris@8 149 ViewManager::setToolMode(ToolMode mode)
Chris@8 150 {
Chris@8 151 m_toolMode = mode;
Chris@8 152
Chris@8 153 emit toolModeChanged();
Chris@8 154 }
Chris@8 155
Chris@0 156 void
Chris@0 157 ViewManager::setAudioPlaySource(AudioPlaySource *source)
Chris@0 158 {
Chris@0 159 if (!m_playSource) {
Chris@0 160 QTimer::singleShot(100, this, SLOT(checkPlayStatus()));
Chris@0 161 }
Chris@0 162 m_playSource = source;
Chris@0 163 }
Chris@0 164
Chris@0 165 PlayParameters *
Chris@0 166 ViewManager::getPlayParameters(const Model *model)
Chris@0 167 {
Chris@0 168 if (m_playParameters.find(model) == m_playParameters.end()) {
Chris@0 169 // Give all models the same type of play parameters for the moment
Chris@0 170 m_playParameters[model] = new PlayParameters;
Chris@0 171 }
Chris@0 172
Chris@0 173 return m_playParameters[model];
Chris@0 174 }
Chris@0 175
Chris@0 176 void
Chris@0 177 ViewManager::clearPlayParameters()
Chris@0 178 {
Chris@0 179 while (!m_playParameters.empty()) {
Chris@0 180 delete m_playParameters.begin()->second;
Chris@0 181 m_playParameters.erase(m_playParameters.begin());
Chris@0 182 }
Chris@0 183 }
Chris@0 184
Chris@0 185 void
Chris@0 186 ViewManager::checkPlayStatus()
Chris@0 187 {
Chris@0 188 if (m_playSource && m_playSource->isPlaying()) {
Chris@0 189
Chris@0 190 float left = 0, right = 0;
Chris@0 191 if (m_playSource->getOutputLevels(left, right)) {
Chris@0 192 if (left != m_lastLeft || right != m_lastRight) {
Chris@0 193 emit outputLevelsChanged(left, right);
Chris@0 194 m_lastLeft = left;
Chris@0 195 m_lastRight = right;
Chris@0 196 }
Chris@0 197 }
Chris@0 198
Chris@0 199 m_globalCentreFrame = m_playSource->getCurrentPlayingFrame();
Chris@0 200
Chris@0 201 #ifdef DEBUG_VIEW_MANAGER
Chris@0 202 std::cout << "ViewManager::checkPlayStatus: Playing, frame " << m_globalCentreFrame << ", levels " << m_lastLeft << "," << m_lastRight << std::endl;
Chris@0 203 #endif
Chris@0 204
Chris@0 205 emit playbackFrameChanged(m_globalCentreFrame);
Chris@0 206
Chris@0 207 QTimer::singleShot(20, this, SLOT(checkPlayStatus()));
Chris@0 208
Chris@0 209 } else {
Chris@0 210
Chris@0 211 QTimer::singleShot(100, this, SLOT(checkPlayStatus()));
Chris@0 212
Chris@0 213 if (m_lastLeft != 0.0 || m_lastRight != 0.0) {
Chris@0 214 emit outputLevelsChanged(0.0, 0.0);
Chris@0 215 m_lastLeft = 0.0;
Chris@0 216 m_lastRight = 0.0;
Chris@0 217 }
Chris@0 218
Chris@0 219 #ifdef DEBUG_VIEW_MANAGER
Chris@0 220 // std::cout << "ViewManager::checkPlayStatus: Not playing" << std::endl;
Chris@0 221 #endif
Chris@0 222 }
Chris@0 223 }
Chris@0 224
Chris@8 225 bool
Chris@8 226 ViewManager::isPlaying() const
Chris@8 227 {
Chris@8 228 return m_playSource && m_playSource->isPlaying();
Chris@8 229 }
Chris@8 230
Chris@0 231 void
Chris@0 232 ViewManager::considerSeek(void *p, unsigned long f, bool locked)
Chris@0 233 {
Chris@0 234 if (locked) {
Chris@0 235 m_globalCentreFrame = f;
Chris@0 236 }
Chris@0 237
Chris@0 238 #ifdef DEBUG_VIEW_MANAGER
Chris@0 239 std::cout << "ViewManager::considerSeek(" << p << ", " << f << ", " << locked << ")" << std::endl;
Chris@0 240 #endif
Chris@0 241
Chris@0 242 if (p == this || !locked) return;
Chris@0 243
Chris@0 244 if (m_playSource && m_playSource->isPlaying()) {
Chris@0 245 unsigned long playFrame = m_playSource->getCurrentPlayingFrame();
Chris@0 246 unsigned long diff = std::max(f, playFrame) - std::min(f, playFrame);
Chris@0 247 if (diff > 20000) {
Chris@0 248 m_playSource->play(f);
Chris@0 249 #ifdef DEBUG_VIEW_MANAGER
Chris@0 250 std::cout << "ViewManager::considerSeek: reseeking from " << playFrame << " to " << f << std::endl;
Chris@0 251 #endif
Chris@0 252 }
Chris@0 253 }
Chris@0 254 }
Chris@0 255
Chris@0 256 void
Chris@0 257 ViewManager::considerZoomChange(void *p, unsigned long z, bool locked)
Chris@0 258 {
Chris@0 259 if (locked) {
Chris@0 260 m_globalZoom = z;
Chris@0 261 }
Chris@0 262
Chris@0 263 #ifdef DEBUG_VIEW_MANAGER
Chris@0 264 std::cout << "ViewManager::considerZoomChange(" << p << ", " << z << ", " << locked << ")" << std::endl;
Chris@0 265 #endif
Chris@0 266 }
Chris@0 267
Chris@0 268 #ifdef INCLUDE_MOCFILES
Chris@0 269 #include "ViewManager.moc.cpp"
Chris@0 270 #endif
Chris@0 271