| 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@127 | 21 | 
| Chris@127 | 22 #include <map> | 
| Chris@127 | 23 | 
| Chris@128 | 24 #include "base/Selection.h" | 
| Chris@128 | 25 #include "base/Command.h" | 
| Chris@128 | 26 #include "base/Clipboard.h" | 
| Chris@127 | 27 | 
| Chris@127 | 28 class AudioPlaySource; | 
| Chris@127 | 29 class Model; | 
| Chris@127 | 30 | 
| Chris@211 | 31 enum PlaybackFollowMode { | 
| Chris@211 | 32     PlaybackScrollContinuous, | 
| Chris@211 | 33     PlaybackScrollPage, | 
| Chris@211 | 34     PlaybackIgnore | 
| Chris@211 | 35 }; | 
| Chris@211 | 36 | 
| Chris@211 | 37 class View; | 
| Chris@211 | 38 | 
| Chris@127 | 39 /** | 
| Chris@127 | 40  * The ViewManager manages properties that may need to be synchronised | 
| Chris@127 | 41  * between separate Views.  For example, it handles signals associated | 
| Chris@127 | 42  * with changes to the global pan and zoom, and it handles selections. | 
| Chris@127 | 43  * | 
| Chris@127 | 44  * Views should be implemented in such a way as to work | 
| Chris@127 | 45  * correctly whether they are supplied with a ViewManager or not. | 
| Chris@127 | 46  */ | 
| Chris@127 | 47 | 
| Chris@127 | 48 class ViewManager : public QObject | 
| Chris@127 | 49 { | 
| Chris@127 | 50     Q_OBJECT | 
| Chris@127 | 51 | 
| Chris@127 | 52 public: | 
| Chris@127 | 53     ViewManager(); | 
| Chris@127 | 54     virtual ~ViewManager(); | 
| Chris@127 | 55 | 
| Chris@127 | 56     void setAudioPlaySource(AudioPlaySource *source); | 
| Chris@127 | 57 | 
| Chris@127 | 58     bool isPlaying() const; | 
| Chris@127 | 59 | 
| Chris@127 | 60     unsigned long getGlobalCentreFrame() const; | 
| Chris@180 | 61     void setGlobalCentreFrame(unsigned long); | 
| Chris@127 | 62     unsigned long getGlobalZoom() const; | 
| Chris@127 | 63 | 
| Chris@127 | 64     unsigned long getPlaybackFrame() const; | 
| Chris@127 | 65     void setPlaybackFrame(unsigned long frame); | 
| Chris@127 | 66 | 
| Chris@127 | 67     bool haveInProgressSelection() const; | 
| Chris@127 | 68     const Selection &getInProgressSelection(bool &exclusive) const; | 
| Chris@127 | 69     void setInProgressSelection(const Selection &selection, bool exclusive); | 
| Chris@127 | 70     void clearInProgressSelection(); | 
| Chris@127 | 71 | 
| Chris@127 | 72     const MultiSelection &getSelection() const; | 
| Chris@127 | 73 | 
| Chris@127 | 74     const MultiSelection::SelectionList &getSelections() const; | 
| Chris@127 | 75     void setSelection(const Selection &selection); | 
| Chris@127 | 76     void addSelection(const Selection &selection); | 
| Chris@127 | 77     void removeSelection(const Selection &selection); | 
| Chris@127 | 78     void clearSelections(); | 
| Chris@271 | 79     size_t constrainFrameToSelection(size_t frame) const; | 
| Chris@127 | 80 | 
| Chris@127 | 81     /** | 
| Chris@127 | 82      * Return the selection that contains a given frame. | 
| Chris@127 | 83      * If defaultToFollowing is true, and if the frame is not in a | 
| Chris@127 | 84      * selected area, return the next selection after the given frame. | 
| Chris@127 | 85      * Return the empty selection if no appropriate selection is found. | 
| Chris@127 | 86      */ | 
| Chris@127 | 87     Selection getContainingSelection(size_t frame, bool defaultToFollowing) const; | 
| Chris@127 | 88 | 
| Chris@127 | 89     Clipboard &getClipboard() { return m_clipboard; } | 
| Chris@127 | 90 | 
| Chris@127 | 91     enum ToolMode { | 
| Chris@127 | 92 	NavigateMode, | 
| Chris@127 | 93 	SelectMode, | 
| Chris@127 | 94         EditMode, | 
| Chris@257 | 95 	DrawMode, | 
| Chris@257 | 96 	MeasureMode | 
| Chris@127 | 97     }; | 
| Chris@127 | 98     ToolMode getToolMode() const { return m_toolMode; } | 
| Chris@127 | 99     void setToolMode(ToolMode mode); | 
| Chris@127 | 100 | 
| Chris@127 | 101     bool getPlayLoopMode() const { return m_playLoopMode; } | 
| Chris@127 | 102     void setPlayLoopMode(bool on); | 
| Chris@127 | 103 | 
| Chris@127 | 104     bool getPlaySelectionMode() const { return m_playSelectionMode; } | 
| Chris@127 | 105     void setPlaySelectionMode(bool on); | 
| Chris@127 | 106 | 
| Chris@224 | 107     /** | 
| Chris@224 | 108      * The sample rate that is used for playback.  This is usually the | 
| Chris@224 | 109      * rate of the main model, but not always.  Models whose rates | 
| Chris@224 | 110      * differ from this will play back at the wrong speed -- there is | 
| Chris@224 | 111      * no per-model resampler. | 
| Chris@224 | 112      */ | 
| Chris@127 | 113     size_t getPlaybackSampleRate() const; | 
| Chris@224 | 114 | 
| Chris@224 | 115     /** | 
| Chris@224 | 116      * The sample rate of the audio output device.  If the playback | 
| Chris@224 | 117      * sample rate differs from this, everything will be resampled at | 
| Chris@224 | 118      * the output stage. | 
| Chris@224 | 119      */ | 
| Chris@224 | 120     size_t getOutputSampleRate() const; | 
| Chris@224 | 121 | 
| Chris@224 | 122     /** | 
| Chris@224 | 123      * The sample rate of the current main model.  This may in theory | 
| Chris@224 | 124      * differ from the playback sample rate, in which case even the | 
| Chris@224 | 125      * main model will play at the wrong speed. | 
| Chris@224 | 126      */ | 
| Chris@127 | 127     size_t getMainModelSampleRate() const { return m_mainModelSampleRate; } | 
| Chris@224 | 128 | 
| Chris@127 | 129     void setMainModelSampleRate(size_t sr) { m_mainModelSampleRate = sr; } | 
| Chris@127 | 130 | 
| Chris@127 | 131     enum OverlayMode { | 
| Chris@127 | 132         NoOverlays, | 
| Chris@189 | 133         MinimalOverlays, | 
| Chris@189 | 134         StandardOverlays, | 
| Chris@127 | 135         AllOverlays | 
| Chris@127 | 136     }; | 
| Chris@127 | 137     void setOverlayMode(OverlayMode mode); | 
| Chris@127 | 138     OverlayMode getOverlayMode() const { return m_overlayMode; } | 
| Chris@127 | 139 | 
| Chris@189 | 140     bool shouldShowCentreLine() const { | 
| Chris@189 | 141         return m_overlayMode != NoOverlays; | 
| Chris@189 | 142     } | 
| Chris@189 | 143     bool shouldShowFrameCount() const { | 
| Chris@189 | 144         return m_overlayMode != NoOverlays; | 
| Chris@189 | 145     } | 
| Chris@189 | 146     bool shouldShowDuration() const { | 
| Chris@189 | 147         return m_overlayMode > MinimalOverlays; | 
| Chris@189 | 148     } | 
| Chris@189 | 149     bool shouldShowVerticalScale() const { | 
| Chris@189 | 150         return m_overlayMode > MinimalOverlays; | 
| Chris@189 | 151     } | 
| Chris@189 | 152     bool shouldShowSelectionExtents() const { | 
| Chris@189 | 153         return m_overlayMode > MinimalOverlays; | 
| Chris@189 | 154     } | 
| Chris@189 | 155     bool shouldShowLayerNames() const { | 
| Chris@189 | 156         return m_overlayMode == AllOverlays; | 
| Chris@189 | 157     } | 
| Chris@195 | 158     bool shouldShowScaleGuides() const { | 
| Chris@195 | 159         return m_overlayMode != NoOverlays; | 
| Chris@195 | 160     } | 
| Chris@189 | 161 | 
| Chris@133 | 162     void setZoomWheelsEnabled(bool enable); | 
| Chris@133 | 163     bool getZoomWheelsEnabled() const { return m_zoomWheelsEnabled; } | 
| Chris@133 | 164 | 
| Chris@127 | 165 signals: | 
| Chris@211 | 166     /** Emitted when user causes the global centre frame to change. */ | 
| Chris@211 | 167     void globalCentreFrameChanged(unsigned long frame); | 
| Chris@127 | 168 | 
| Chris@211 | 169     /** Emitted when user scrolls a view, but doesn't affect global centre. */ | 
| Chris@211 | 170     void viewCentreFrameChanged(View *v, unsigned long frame); | 
| Chris@211 | 171 | 
| Chris@211 | 172     /** Emitted when a view zooms. */ | 
| Chris@222 | 173     void viewZoomLevelChanged(View *v, unsigned long zoom, bool locked); | 
| Chris@133 | 174 | 
| Chris@127 | 175     /** Emitted when the playback frame changes. */ | 
| Chris@127 | 176     void playbackFrameChanged(unsigned long frame); | 
| Chris@127 | 177 | 
| Chris@127 | 178     /** Emitted when the output levels change. Values in range 0.0 -> 1.0. */ | 
| Chris@127 | 179     void outputLevelsChanged(float left, float right); | 
| Chris@127 | 180 | 
| Chris@127 | 181     /** Emitted when the selection has changed. */ | 
| Chris@127 | 182     void selectionChanged(); | 
| Chris@127 | 183 | 
| Chris@127 | 184     /** Emitted when the in-progress (rubberbanding) selection has changed. */ | 
| Chris@127 | 185     void inProgressSelectionChanged(); | 
| Chris@127 | 186 | 
| Chris@127 | 187     /** Emitted when the tool mode has been changed. */ | 
| Chris@127 | 188     void toolModeChanged(); | 
| Chris@127 | 189 | 
| Chris@127 | 190     /** Emitted when the play loop mode has been changed. */ | 
| Chris@127 | 191     void playLoopModeChanged(); | 
| Chris@177 | 192     void playLoopModeChanged(bool); | 
| Chris@127 | 193 | 
| Chris@127 | 194     /** Emitted when the play selection mode has been changed. */ | 
| Chris@127 | 195     void playSelectionModeChanged(); | 
| Chris@177 | 196     void playSelectionModeChanged(bool); | 
| Chris@127 | 197 | 
| Chris@127 | 198     /** Emitted when the overlay mode has been changed. */ | 
| Chris@127 | 199     void overlayModeChanged(); | 
| Chris@127 | 200 | 
| Chris@133 | 201     /** Emitted when the zoom wheels have been toggled. */ | 
| Chris@133 | 202     void zoomWheelsEnabledChanged(); | 
| Chris@133 | 203 | 
| Chris@211 | 204 public slots: | 
| Chris@211 | 205     void viewCentreFrameChanged(unsigned long, bool, PlaybackFollowMode); | 
| Chris@222 | 206     void viewZoomLevelChanged(unsigned long, bool); | 
| Chris@211 | 207 | 
| Chris@127 | 208 protected slots: | 
| Chris@127 | 209     void checkPlayStatus(); | 
| Chris@127 | 210     void playStatusChanged(bool playing); | 
| Chris@211 | 211     void seek(unsigned long); | 
| Chris@222 | 212 //!!!    void considerZoomChange(void *, unsigned long, bool); | 
| Chris@127 | 213 | 
| Chris@127 | 214 protected: | 
| Chris@127 | 215     AudioPlaySource *m_playSource; | 
| Chris@127 | 216     unsigned long m_globalCentreFrame; | 
| Chris@127 | 217     unsigned long m_globalZoom; | 
| Chris@127 | 218     mutable unsigned long m_playbackFrame; | 
| Chris@127 | 219     size_t m_mainModelSampleRate; | 
| Chris@127 | 220 | 
| Chris@127 | 221     float m_lastLeft; | 
| Chris@127 | 222     float m_lastRight; | 
| Chris@127 | 223 | 
| Chris@127 | 224     MultiSelection m_selections; | 
| Chris@127 | 225     Selection m_inProgressSelection; | 
| Chris@127 | 226     bool m_inProgressExclusive; | 
| Chris@127 | 227 | 
| Chris@127 | 228     Clipboard m_clipboard; | 
| Chris@127 | 229 | 
| Chris@127 | 230     ToolMode m_toolMode; | 
| Chris@127 | 231 | 
| Chris@127 | 232     bool m_playLoopMode; | 
| Chris@127 | 233     bool m_playSelectionMode; | 
| Chris@127 | 234 | 
| Chris@127 | 235     void setSelections(const MultiSelection &ms); | 
| Chris@127 | 236     void signalSelectionChange(); | 
| Chris@127 | 237 | 
| Chris@127 | 238     class SetSelectionCommand : public Command | 
| Chris@127 | 239     { | 
| Chris@127 | 240     public: | 
| Chris@127 | 241 	SetSelectionCommand(ViewManager *vm, const MultiSelection &ms); | 
| Chris@127 | 242 	virtual ~SetSelectionCommand(); | 
| Chris@127 | 243 	virtual void execute(); | 
| Chris@127 | 244 	virtual void unexecute(); | 
| Chris@127 | 245 	virtual QString getName() const; | 
| Chris@127 | 246 | 
| Chris@127 | 247     protected: | 
| Chris@127 | 248 	ViewManager *m_vm; | 
| Chris@127 | 249 	MultiSelection m_oldSelection; | 
| Chris@127 | 250 	MultiSelection m_newSelection; | 
| Chris@127 | 251     }; | 
| Chris@127 | 252 | 
| Chris@127 | 253     OverlayMode m_overlayMode; | 
| Chris@133 | 254     bool m_zoomWheelsEnabled; | 
| Chris@127 | 255 }; | 
| Chris@127 | 256 | 
| Chris@127 | 257 #endif | 
| Chris@127 | 258 |