| Chris@127 | 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */ | 
| Chris@127 | 2 | 
| Chris@127 | 3 /* | 
| Chris@127 | 4     Sonic Visualiser | 
| Chris@127 | 5     An audio file viewer and annotation editor. | 
| Chris@127 | 6     Centre for Digital Music, Queen Mary, University of London. | 
| Chris@182 | 7     This file copyright 2006 Chris Cannam and QMUL. | 
| Chris@127 | 8 | 
| Chris@127 | 9     This program is free software; you can redistribute it and/or | 
| Chris@127 | 10     modify it under the terms of the GNU General Public License as | 
| Chris@127 | 11     published by the Free Software Foundation; either version 2 of the | 
| Chris@127 | 12     License, or (at your option) any later version.  See the file | 
| Chris@127 | 13     COPYING included with this distribution for more information. | 
| Chris@127 | 14 */ | 
| Chris@127 | 15 | 
| Chris@127 | 16 #ifndef _VIEW_MANAGER_H_ | 
| Chris@127 | 17 #define _VIEW_MANAGER_H_ | 
| Chris@127 | 18 | 
| Chris@127 | 19 #include <QObject> | 
| Chris@127 | 20 #include <QTimer> | 
| Chris@292 | 21 #include <QPalette> | 
| Chris@127 | 22 | 
| Chris@127 | 23 #include <map> | 
| Chris@127 | 24 | 
| Chris@376 | 25 #include "base/ViewManagerBase.h" | 
| Chris@128 | 26 #include "base/Selection.h" | 
| Chris@128 | 27 #include "base/Command.h" | 
| Chris@128 | 28 #include "base/Clipboard.h" | 
| Chris@127 | 29 | 
| Chris@127 | 30 class AudioPlaySource; | 
| Chris@127 | 31 class Model; | 
| Chris@127 | 32 | 
| Chris@211 | 33 enum PlaybackFollowMode { | 
| Chris@211 | 34     PlaybackScrollContinuous, | 
| Chris@211 | 35     PlaybackScrollPage, | 
| Chris@211 | 36     PlaybackIgnore | 
| Chris@211 | 37 }; | 
| Chris@211 | 38 | 
| Chris@211 | 39 class View; | 
| Chris@211 | 40 | 
| Chris@127 | 41 /** | 
| Chris@127 | 42  * The ViewManager manages properties that may need to be synchronised | 
| Chris@127 | 43  * between separate Views.  For example, it handles signals associated | 
| Chris@127 | 44  * with changes to the global pan and zoom, and it handles selections. | 
| Chris@127 | 45  * | 
| Chris@127 | 46  * Views should be implemented in such a way as to work | 
| Chris@127 | 47  * correctly whether they are supplied with a ViewManager or not. | 
| Chris@127 | 48  */ | 
| Chris@127 | 49 | 
| Chris@376 | 50 class ViewManager : public ViewManagerBase | 
| Chris@127 | 51 { | 
| Chris@127 | 52     Q_OBJECT | 
| Chris@127 | 53 | 
| Chris@127 | 54 public: | 
| Chris@127 | 55     ViewManager(); | 
| Chris@127 | 56     virtual ~ViewManager(); | 
| Chris@127 | 57 | 
| Chris@127 | 58     void setAudioPlaySource(AudioPlaySource *source); | 
| Chris@127 | 59 | 
| Chris@127 | 60     bool isPlaying() const; | 
| Chris@127 | 61 | 
| Chris@394 | 62     unsigned long getGlobalCentreFrame() const; // the set method is a slot | 
| Chris@127 | 63     unsigned long getGlobalZoom() const; | 
| Chris@127 | 64 | 
| Chris@394 | 65     unsigned long getPlaybackFrame() const; // the set method is a slot | 
| Chris@127 | 66 | 
| Chris@301 | 67     // Only meaningful in solo mode, and used for optional alignment feature | 
| Chris@301 | 68     Model *getPlaybackModel() const; | 
| Chris@301 | 69     void setPlaybackModel(Model *); | 
| Chris@301 | 70 | 
| Chris@333 | 71     size_t alignPlaybackFrameToReference(size_t) const; | 
| Chris@333 | 72     size_t alignReferenceToPlaybackFrame(size_t) const; | 
| Chris@333 | 73 | 
| Chris@127 | 74     bool haveInProgressSelection() const; | 
| Chris@127 | 75     const Selection &getInProgressSelection(bool &exclusive) const; | 
| Chris@127 | 76     void setInProgressSelection(const Selection &selection, bool exclusive); | 
| Chris@127 | 77     void clearInProgressSelection(); | 
| Chris@127 | 78 | 
| Chris@127 | 79     const MultiSelection &getSelection() const; | 
| Chris@127 | 80 | 
| Chris@127 | 81     const MultiSelection::SelectionList &getSelections() const; | 
| Chris@127 | 82     void setSelection(const Selection &selection); | 
| Chris@127 | 83     void addSelection(const Selection &selection); | 
| Chris@127 | 84     void removeSelection(const Selection &selection); | 
| Chris@127 | 85     void clearSelections(); | 
| Chris@271 | 86     size_t constrainFrameToSelection(size_t frame) const; | 
| Chris@127 | 87 | 
| Chris@127 | 88     /** | 
| Chris@127 | 89      * Return the selection that contains a given frame. | 
| Chris@127 | 90      * If defaultToFollowing is true, and if the frame is not in a | 
| Chris@127 | 91      * selected area, return the next selection after the given frame. | 
| Chris@127 | 92      * Return the empty selection if no appropriate selection is found. | 
| Chris@127 | 93      */ | 
| Chris@127 | 94     Selection getContainingSelection(size_t frame, bool defaultToFollowing) const; | 
| Chris@127 | 95 | 
| Chris@127 | 96     Clipboard &getClipboard() { return m_clipboard; } | 
| Chris@127 | 97 | 
| Chris@127 | 98     enum ToolMode { | 
| Chris@127 | 99 	NavigateMode, | 
| Chris@127 | 100 	SelectMode, | 
| Chris@127 | 101         EditMode, | 
| Chris@257 | 102 	DrawMode, | 
| Chris@335 | 103 	EraseMode, | 
| Chris@257 | 104 	MeasureMode | 
| Chris@127 | 105     }; | 
| Chris@127 | 106     ToolMode getToolMode() const { return m_toolMode; } | 
| Chris@127 | 107     void setToolMode(ToolMode mode); | 
| Chris@127 | 108 | 
| Chris@127 | 109     bool getPlayLoopMode() const { return m_playLoopMode; } | 
| Chris@127 | 110     void setPlayLoopMode(bool on); | 
| Chris@127 | 111 | 
| Chris@127 | 112     bool getPlaySelectionMode() const { return m_playSelectionMode; } | 
| Chris@127 | 113     void setPlaySelectionMode(bool on); | 
| Chris@127 | 114 | 
| Chris@301 | 115     bool getPlaySoloMode() const { return m_playSoloMode; } | 
| Chris@301 | 116     void setPlaySoloMode(bool on); | 
| Chris@301 | 117 | 
| Chris@314 | 118     bool getAlignMode() const { return m_alignMode; } | 
| Chris@314 | 119     void setAlignMode(bool on); | 
| Chris@314 | 120 | 
| Chris@326 | 121     void setIlluminateLocalFeatures(bool i) { m_illuminateLocalFeatures = i; } | 
| Chris@326 | 122     void setShowWorkTitle(bool show) { m_showWorkTitle = show; } | 
| Chris@326 | 123 | 
| Chris@224 | 124     /** | 
| Chris@224 | 125      * The sample rate that is used for playback.  This is usually the | 
| Chris@224 | 126      * rate of the main model, but not always.  Models whose rates | 
| Chris@224 | 127      * differ from this will play back at the wrong speed -- there is | 
| Chris@224 | 128      * no per-model resampler. | 
| Chris@224 | 129      */ | 
| Chris@127 | 130     size_t getPlaybackSampleRate() const; | 
| Chris@224 | 131 | 
| Chris@224 | 132     /** | 
| Chris@224 | 133      * The sample rate of the audio output device.  If the playback | 
| Chris@224 | 134      * sample rate differs from this, everything will be resampled at | 
| Chris@224 | 135      * the output stage. | 
| Chris@224 | 136      */ | 
| Chris@224 | 137     size_t getOutputSampleRate() const; | 
| Chris@224 | 138 | 
| Chris@224 | 139     /** | 
| Chris@224 | 140      * The sample rate of the current main model.  This may in theory | 
| Chris@224 | 141      * differ from the playback sample rate, in which case even the | 
| Chris@224 | 142      * main model will play at the wrong speed. | 
| Chris@224 | 143      */ | 
| Chris@127 | 144     size_t getMainModelSampleRate() const { return m_mainModelSampleRate; } | 
| Chris@224 | 145 | 
| Chris@127 | 146     void setMainModelSampleRate(size_t sr) { m_mainModelSampleRate = sr; } | 
| Chris@127 | 147 | 
| Chris@127 | 148     enum OverlayMode { | 
| Chris@127 | 149         NoOverlays, | 
| Chris@189 | 150         MinimalOverlays, | 
| Chris@189 | 151         StandardOverlays, | 
| Chris@127 | 152         AllOverlays | 
| Chris@127 | 153     }; | 
| Chris@127 | 154     void setOverlayMode(OverlayMode mode); | 
| Chris@127 | 155     OverlayMode getOverlayMode() const { return m_overlayMode; } | 
| Chris@127 | 156 | 
| Chris@189 | 157     bool shouldShowCentreLine() const { | 
| Chris@189 | 158         return m_overlayMode != NoOverlays; | 
| Chris@189 | 159     } | 
| Chris@189 | 160     bool shouldShowFrameCount() const { | 
| Chris@189 | 161         return m_overlayMode != NoOverlays; | 
| Chris@189 | 162     } | 
| Chris@189 | 163     bool shouldShowDuration() const { | 
| Chris@189 | 164         return m_overlayMode > MinimalOverlays; | 
| Chris@189 | 165     } | 
| Chris@189 | 166     bool shouldShowVerticalScale() const { | 
| Chris@189 | 167         return m_overlayMode > MinimalOverlays; | 
| Chris@189 | 168     } | 
| Chris@189 | 169     bool shouldShowSelectionExtents() const { | 
| Chris@189 | 170         return m_overlayMode > MinimalOverlays; | 
| Chris@189 | 171     } | 
| Chris@189 | 172     bool shouldShowLayerNames() const { | 
| Chris@189 | 173         return m_overlayMode == AllOverlays; | 
| Chris@189 | 174     } | 
| Chris@195 | 175     bool shouldShowScaleGuides() const { | 
| Chris@195 | 176         return m_overlayMode != NoOverlays; | 
| Chris@195 | 177     } | 
| Chris@326 | 178     bool shouldShowWorkTitle() const { | 
| Chris@326 | 179         return m_showWorkTitle; | 
| Chris@326 | 180     } | 
| Chris@326 | 181     bool shouldIlluminateLocalFeatures() const { | 
| Chris@326 | 182         return m_illuminateLocalFeatures; | 
| Chris@326 | 183     } | 
| Chris@189 | 184 | 
| Chris@133 | 185     void setZoomWheelsEnabled(bool enable); | 
| Chris@133 | 186     bool getZoomWheelsEnabled() const { return m_zoomWheelsEnabled; } | 
| Chris@133 | 187 | 
| Chris@292 | 188     void setGlobalDarkBackground(bool dark); | 
| Chris@292 | 189     bool getGlobalDarkBackground() const; | 
| Chris@292 | 190 | 
| Chris@127 | 191 signals: | 
| Chris@211 | 192     /** Emitted when user causes the global centre frame to change. */ | 
| Chris@211 | 193     void globalCentreFrameChanged(unsigned long frame); | 
| Chris@127 | 194 | 
| Chris@211 | 195     /** Emitted when user scrolls a view, but doesn't affect global centre. */ | 
| Chris@211 | 196     void viewCentreFrameChanged(View *v, unsigned long frame); | 
| Chris@211 | 197 | 
| Chris@211 | 198     /** Emitted when a view zooms. */ | 
| Chris@222 | 199     void viewZoomLevelChanged(View *v, unsigned long zoom, bool locked); | 
| Chris@133 | 200 | 
| Chris@127 | 201     /** Emitted when the playback frame changes. */ | 
| Chris@127 | 202     void playbackFrameChanged(unsigned long frame); | 
| Chris@127 | 203 | 
| Chris@127 | 204     /** Emitted when the output levels change. Values in range 0.0 -> 1.0. */ | 
| Chris@127 | 205     void outputLevelsChanged(float left, float right); | 
| Chris@127 | 206 | 
| Chris@127 | 207     /** Emitted when the selection has changed. */ | 
| Chris@127 | 208     void selectionChanged(); | 
| Chris@127 | 209 | 
| Chris@127 | 210     /** Emitted when the in-progress (rubberbanding) selection has changed. */ | 
| Chris@127 | 211     void inProgressSelectionChanged(); | 
| Chris@127 | 212 | 
| Chris@127 | 213     /** Emitted when the tool mode has been changed. */ | 
| Chris@127 | 214     void toolModeChanged(); | 
| Chris@127 | 215 | 
| Chris@127 | 216     /** Emitted when the play loop mode has been changed. */ | 
| Chris@127 | 217     void playLoopModeChanged(); | 
| Chris@177 | 218     void playLoopModeChanged(bool); | 
| Chris@127 | 219 | 
| Chris@127 | 220     /** Emitted when the play selection mode has been changed. */ | 
| Chris@127 | 221     void playSelectionModeChanged(); | 
| Chris@177 | 222     void playSelectionModeChanged(bool); | 
| Chris@127 | 223 | 
| Chris@301 | 224     /** Emitted when the play solo mode has been changed. */ | 
| Chris@301 | 225     void playSoloModeChanged(); | 
| Chris@301 | 226     void playSoloModeChanged(bool); | 
| Chris@301 | 227 | 
| Chris@314 | 228     /** Emitted when the alignment mode has been changed. */ | 
| Chris@314 | 229     void alignModeChanged(); | 
| Chris@314 | 230     void alignModeChanged(bool); | 
| Chris@314 | 231 | 
| Chris@127 | 232     /** Emitted when the overlay mode has been changed. */ | 
| Chris@127 | 233     void overlayModeChanged(); | 
| Chris@127 | 234 | 
| Chris@133 | 235     /** Emitted when the zoom wheels have been toggled. */ | 
| Chris@133 | 236     void zoomWheelsEnabledChanged(); | 
| Chris@133 | 237 | 
| Chris@211 | 238 public slots: | 
| Chris@211 | 239     void viewCentreFrameChanged(unsigned long, bool, PlaybackFollowMode); | 
| Chris@222 | 240     void viewZoomLevelChanged(unsigned long, bool); | 
| Chris@394 | 241     void setGlobalCentreFrame(unsigned long); | 
| Chris@394 | 242     void setPlaybackFrame(unsigned long); | 
| Chris@211 | 243 | 
| Chris@127 | 244 protected slots: | 
| Chris@127 | 245     void checkPlayStatus(); | 
| Chris@127 | 246     void playStatusChanged(bool playing); | 
| Chris@211 | 247     void seek(unsigned long); | 
| Chris@222 | 248 //!!!    void considerZoomChange(void *, unsigned long, bool); | 
| Chris@127 | 249 | 
| Chris@127 | 250 protected: | 
| Chris@127 | 251     AudioPlaySource *m_playSource; | 
| Chris@127 | 252     unsigned long m_globalCentreFrame; | 
| Chris@127 | 253     unsigned long m_globalZoom; | 
| Chris@127 | 254     mutable unsigned long m_playbackFrame; | 
| Chris@301 | 255     Model *m_playbackModel; //!!! | 
| Chris@127 | 256     size_t m_mainModelSampleRate; | 
| Chris@127 | 257 | 
| Chris@127 | 258     float m_lastLeft; | 
| Chris@127 | 259     float m_lastRight; | 
| Chris@127 | 260 | 
| Chris@127 | 261     MultiSelection m_selections; | 
| Chris@127 | 262     Selection m_inProgressSelection; | 
| Chris@127 | 263     bool m_inProgressExclusive; | 
| Chris@127 | 264 | 
| Chris@127 | 265     Clipboard m_clipboard; | 
| Chris@127 | 266 | 
| Chris@127 | 267     ToolMode m_toolMode; | 
| Chris@127 | 268 | 
| Chris@127 | 269     bool m_playLoopMode; | 
| Chris@127 | 270     bool m_playSelectionMode; | 
| Chris@301 | 271     bool m_playSoloMode; | 
| Chris@314 | 272     bool m_alignMode; | 
| Chris@127 | 273 | 
| Chris@127 | 274     void setSelections(const MultiSelection &ms); | 
| Chris@127 | 275     void signalSelectionChange(); | 
| Chris@127 | 276 | 
| Chris@127 | 277     class SetSelectionCommand : public Command | 
| Chris@127 | 278     { | 
| Chris@127 | 279     public: | 
| Chris@127 | 280 	SetSelectionCommand(ViewManager *vm, const MultiSelection &ms); | 
| Chris@127 | 281 	virtual ~SetSelectionCommand(); | 
| Chris@127 | 282 	virtual void execute(); | 
| Chris@127 | 283 	virtual void unexecute(); | 
| Chris@127 | 284 	virtual QString getName() const; | 
| Chris@127 | 285 | 
| Chris@127 | 286     protected: | 
| Chris@127 | 287 	ViewManager *m_vm; | 
| Chris@127 | 288 	MultiSelection m_oldSelection; | 
| Chris@127 | 289 	MultiSelection m_newSelection; | 
| Chris@127 | 290     }; | 
| Chris@127 | 291 | 
| Chris@127 | 292     OverlayMode m_overlayMode; | 
| Chris@133 | 293     bool m_zoomWheelsEnabled; | 
| Chris@326 | 294     bool m_illuminateLocalFeatures; | 
| Chris@326 | 295     bool m_showWorkTitle; | 
| Chris@292 | 296 | 
| Chris@292 | 297     QPalette m_lightPalette; | 
| Chris@292 | 298     QPalette m_darkPalette; | 
| Chris@127 | 299 }; | 
| Chris@127 | 300 | 
| Chris@127 | 301 #endif | 
| Chris@127 | 302 |