annotate view/ViewManager.h @ 333:e74b56f07c73

* Some work on correct alignment when moving panes during playback * Overhaul alignment for playback frame values (view manager now always refers to reference-timeline values, only the play source deals in playback model timeline values) * When making a selection, ensure the selection regions shown in other panes (and used for playback constraints if appropriate) are aligned correctly. This may be the coolest feature ever implemented in any program ever.
author Chris Cannam
date Thu, 22 Nov 2007 14:17:19 +0000
parents 4f4f38a11cd2
children 2f83b6e3b8ca
rev   line source
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@128 25 #include "base/Selection.h"
Chris@128 26 #include "base/Command.h"
Chris@128 27 #include "base/Clipboard.h"
Chris@127 28
Chris@127 29 class AudioPlaySource;
Chris@127 30 class Model;
Chris@127 31
Chris@211 32 enum PlaybackFollowMode {
Chris@211 33 PlaybackScrollContinuous,
Chris@211 34 PlaybackScrollPage,
Chris@211 35 PlaybackIgnore
Chris@211 36 };
Chris@211 37
Chris@211 38 class View;
Chris@211 39
Chris@127 40 /**
Chris@127 41 * The ViewManager manages properties that may need to be synchronised
Chris@127 42 * between separate Views. For example, it handles signals associated
Chris@127 43 * with changes to the global pan and zoom, and it handles selections.
Chris@127 44 *
Chris@127 45 * Views should be implemented in such a way as to work
Chris@127 46 * correctly whether they are supplied with a ViewManager or not.
Chris@127 47 */
Chris@127 48
Chris@127 49 class ViewManager : public QObject
Chris@127 50 {
Chris@127 51 Q_OBJECT
Chris@127 52
Chris@127 53 public:
Chris@127 54 ViewManager();
Chris@127 55 virtual ~ViewManager();
Chris@127 56
Chris@127 57 void setAudioPlaySource(AudioPlaySource *source);
Chris@127 58
Chris@127 59 bool isPlaying() const;
Chris@127 60
Chris@127 61 unsigned long getGlobalCentreFrame() const;
Chris@180 62 void setGlobalCentreFrame(unsigned long);
Chris@127 63 unsigned long getGlobalZoom() const;
Chris@127 64
Chris@127 65 unsigned long getPlaybackFrame() const;
Chris@127 66 void setPlaybackFrame(unsigned long frame);
Chris@127 67
Chris@301 68 // Only meaningful in solo mode, and used for optional alignment feature
Chris@333 69
Chris@333 70 //!!! We probably don't want to do this. It's probably better to
Chris@333 71 // always have playback frame aligned against the reference model,
Chris@333 72 // and have the ViewManager know which is the reference model.
Chris@333 73 // That way the ViewManager can assume that all Views report in
Chris@333 74 // reference model timeline, and it can convert the playback frame
Chris@333 75 // received from the play source (which always operates in literal
Chris@333 76 // audio sample frames, i.e. playback model timeline) to the
Chris@333 77 // reference timeline itself so the view never has to worry about
Chris@333 78 // the difference between playback and reference model. Of course
Chris@333 79 // that does mean the ViewManager needs to know about both.
Chris@333 80
Chris@301 81 Model *getPlaybackModel() const;
Chris@301 82 void setPlaybackModel(Model *);
Chris@301 83
Chris@333 84 size_t alignPlaybackFrameToReference(size_t) const;
Chris@333 85 size_t alignReferenceToPlaybackFrame(size_t) const;
Chris@333 86
Chris@127 87 bool haveInProgressSelection() const;
Chris@127 88 const Selection &getInProgressSelection(bool &exclusive) const;
Chris@127 89 void setInProgressSelection(const Selection &selection, bool exclusive);
Chris@127 90 void clearInProgressSelection();
Chris@127 91
Chris@127 92 const MultiSelection &getSelection() const;
Chris@127 93
Chris@127 94 const MultiSelection::SelectionList &getSelections() const;
Chris@127 95 void setSelection(const Selection &selection);
Chris@127 96 void addSelection(const Selection &selection);
Chris@127 97 void removeSelection(const Selection &selection);
Chris@127 98 void clearSelections();
Chris@271 99 size_t constrainFrameToSelection(size_t frame) const;
Chris@127 100
Chris@127 101 /**
Chris@127 102 * Return the selection that contains a given frame.
Chris@127 103 * If defaultToFollowing is true, and if the frame is not in a
Chris@127 104 * selected area, return the next selection after the given frame.
Chris@127 105 * Return the empty selection if no appropriate selection is found.
Chris@127 106 */
Chris@127 107 Selection getContainingSelection(size_t frame, bool defaultToFollowing) const;
Chris@127 108
Chris@127 109 Clipboard &getClipboard() { return m_clipboard; }
Chris@127 110
Chris@127 111 enum ToolMode {
Chris@127 112 NavigateMode,
Chris@127 113 SelectMode,
Chris@127 114 EditMode,
Chris@257 115 DrawMode,
Chris@257 116 MeasureMode
Chris@127 117 };
Chris@127 118 ToolMode getToolMode() const { return m_toolMode; }
Chris@127 119 void setToolMode(ToolMode mode);
Chris@127 120
Chris@127 121 bool getPlayLoopMode() const { return m_playLoopMode; }
Chris@127 122 void setPlayLoopMode(bool on);
Chris@127 123
Chris@127 124 bool getPlaySelectionMode() const { return m_playSelectionMode; }
Chris@127 125 void setPlaySelectionMode(bool on);
Chris@127 126
Chris@301 127 bool getPlaySoloMode() const { return m_playSoloMode; }
Chris@301 128 void setPlaySoloMode(bool on);
Chris@301 129
Chris@314 130 bool getAlignMode() const { return m_alignMode; }
Chris@314 131 void setAlignMode(bool on);
Chris@314 132
Chris@326 133 void setIlluminateLocalFeatures(bool i) { m_illuminateLocalFeatures = i; }
Chris@326 134 void setShowWorkTitle(bool show) { m_showWorkTitle = show; }
Chris@326 135
Chris@224 136 /**
Chris@224 137 * The sample rate that is used for playback. This is usually the
Chris@224 138 * rate of the main model, but not always. Models whose rates
Chris@224 139 * differ from this will play back at the wrong speed -- there is
Chris@224 140 * no per-model resampler.
Chris@224 141 */
Chris@127 142 size_t getPlaybackSampleRate() const;
Chris@224 143
Chris@224 144 /**
Chris@224 145 * The sample rate of the audio output device. If the playback
Chris@224 146 * sample rate differs from this, everything will be resampled at
Chris@224 147 * the output stage.
Chris@224 148 */
Chris@224 149 size_t getOutputSampleRate() const;
Chris@224 150
Chris@224 151 /**
Chris@224 152 * The sample rate of the current main model. This may in theory
Chris@224 153 * differ from the playback sample rate, in which case even the
Chris@224 154 * main model will play at the wrong speed.
Chris@224 155 */
Chris@127 156 size_t getMainModelSampleRate() const { return m_mainModelSampleRate; }
Chris@224 157
Chris@127 158 void setMainModelSampleRate(size_t sr) { m_mainModelSampleRate = sr; }
Chris@127 159
Chris@127 160 enum OverlayMode {
Chris@127 161 NoOverlays,
Chris@189 162 MinimalOverlays,
Chris@189 163 StandardOverlays,
Chris@127 164 AllOverlays
Chris@127 165 };
Chris@127 166 void setOverlayMode(OverlayMode mode);
Chris@127 167 OverlayMode getOverlayMode() const { return m_overlayMode; }
Chris@127 168
Chris@189 169 bool shouldShowCentreLine() const {
Chris@189 170 return m_overlayMode != NoOverlays;
Chris@189 171 }
Chris@189 172 bool shouldShowFrameCount() const {
Chris@189 173 return m_overlayMode != NoOverlays;
Chris@189 174 }
Chris@189 175 bool shouldShowDuration() const {
Chris@189 176 return m_overlayMode > MinimalOverlays;
Chris@189 177 }
Chris@189 178 bool shouldShowVerticalScale() const {
Chris@189 179 return m_overlayMode > MinimalOverlays;
Chris@189 180 }
Chris@189 181 bool shouldShowSelectionExtents() const {
Chris@189 182 return m_overlayMode > MinimalOverlays;
Chris@189 183 }
Chris@189 184 bool shouldShowLayerNames() const {
Chris@189 185 return m_overlayMode == AllOverlays;
Chris@189 186 }
Chris@195 187 bool shouldShowScaleGuides() const {
Chris@195 188 return m_overlayMode != NoOverlays;
Chris@195 189 }
Chris@326 190 bool shouldShowWorkTitle() const {
Chris@326 191 return m_showWorkTitle;
Chris@326 192 }
Chris@326 193 bool shouldIlluminateLocalFeatures() const {
Chris@326 194 return m_illuminateLocalFeatures;
Chris@326 195 }
Chris@189 196
Chris@133 197 void setZoomWheelsEnabled(bool enable);
Chris@133 198 bool getZoomWheelsEnabled() const { return m_zoomWheelsEnabled; }
Chris@133 199
Chris@292 200 void setGlobalDarkBackground(bool dark);
Chris@292 201 bool getGlobalDarkBackground() const;
Chris@292 202
Chris@127 203 signals:
Chris@211 204 /** Emitted when user causes the global centre frame to change. */
Chris@211 205 void globalCentreFrameChanged(unsigned long frame);
Chris@127 206
Chris@211 207 /** Emitted when user scrolls a view, but doesn't affect global centre. */
Chris@211 208 void viewCentreFrameChanged(View *v, unsigned long frame);
Chris@211 209
Chris@211 210 /** Emitted when a view zooms. */
Chris@222 211 void viewZoomLevelChanged(View *v, unsigned long zoom, bool locked);
Chris@133 212
Chris@127 213 /** Emitted when the playback frame changes. */
Chris@127 214 void playbackFrameChanged(unsigned long frame);
Chris@127 215
Chris@127 216 /** Emitted when the output levels change. Values in range 0.0 -> 1.0. */
Chris@127 217 void outputLevelsChanged(float left, float right);
Chris@127 218
Chris@127 219 /** Emitted when the selection has changed. */
Chris@127 220 void selectionChanged();
Chris@127 221
Chris@127 222 /** Emitted when the in-progress (rubberbanding) selection has changed. */
Chris@127 223 void inProgressSelectionChanged();
Chris@127 224
Chris@127 225 /** Emitted when the tool mode has been changed. */
Chris@127 226 void toolModeChanged();
Chris@127 227
Chris@127 228 /** Emitted when the play loop mode has been changed. */
Chris@127 229 void playLoopModeChanged();
Chris@177 230 void playLoopModeChanged(bool);
Chris@127 231
Chris@127 232 /** Emitted when the play selection mode has been changed. */
Chris@127 233 void playSelectionModeChanged();
Chris@177 234 void playSelectionModeChanged(bool);
Chris@127 235
Chris@301 236 /** Emitted when the play solo mode has been changed. */
Chris@301 237 void playSoloModeChanged();
Chris@301 238 void playSoloModeChanged(bool);
Chris@301 239
Chris@314 240 /** Emitted when the alignment mode has been changed. */
Chris@314 241 void alignModeChanged();
Chris@314 242 void alignModeChanged(bool);
Chris@314 243
Chris@127 244 /** Emitted when the overlay mode has been changed. */
Chris@127 245 void overlayModeChanged();
Chris@127 246
Chris@133 247 /** Emitted when the zoom wheels have been toggled. */
Chris@133 248 void zoomWheelsEnabledChanged();
Chris@133 249
Chris@211 250 public slots:
Chris@211 251 void viewCentreFrameChanged(unsigned long, bool, PlaybackFollowMode);
Chris@222 252 void viewZoomLevelChanged(unsigned long, bool);
Chris@211 253
Chris@127 254 protected slots:
Chris@127 255 void checkPlayStatus();
Chris@127 256 void playStatusChanged(bool playing);
Chris@211 257 void seek(unsigned long);
Chris@222 258 //!!! void considerZoomChange(void *, unsigned long, bool);
Chris@127 259
Chris@127 260 protected:
Chris@127 261 AudioPlaySource *m_playSource;
Chris@127 262 unsigned long m_globalCentreFrame;
Chris@127 263 unsigned long m_globalZoom;
Chris@127 264 mutable unsigned long m_playbackFrame;
Chris@301 265 Model *m_playbackModel; //!!!
Chris@127 266 size_t m_mainModelSampleRate;
Chris@127 267
Chris@127 268 float m_lastLeft;
Chris@127 269 float m_lastRight;
Chris@127 270
Chris@127 271 MultiSelection m_selections;
Chris@127 272 Selection m_inProgressSelection;
Chris@127 273 bool m_inProgressExclusive;
Chris@127 274
Chris@127 275 Clipboard m_clipboard;
Chris@127 276
Chris@127 277 ToolMode m_toolMode;
Chris@127 278
Chris@127 279 bool m_playLoopMode;
Chris@127 280 bool m_playSelectionMode;
Chris@301 281 bool m_playSoloMode;
Chris@314 282 bool m_alignMode;
Chris@127 283
Chris@127 284 void setSelections(const MultiSelection &ms);
Chris@127 285 void signalSelectionChange();
Chris@127 286
Chris@127 287 class SetSelectionCommand : public Command
Chris@127 288 {
Chris@127 289 public:
Chris@127 290 SetSelectionCommand(ViewManager *vm, const MultiSelection &ms);
Chris@127 291 virtual ~SetSelectionCommand();
Chris@127 292 virtual void execute();
Chris@127 293 virtual void unexecute();
Chris@127 294 virtual QString getName() const;
Chris@127 295
Chris@127 296 protected:
Chris@127 297 ViewManager *m_vm;
Chris@127 298 MultiSelection m_oldSelection;
Chris@127 299 MultiSelection m_newSelection;
Chris@127 300 };
Chris@127 301
Chris@127 302 OverlayMode m_overlayMode;
Chris@133 303 bool m_zoomWheelsEnabled;
Chris@326 304 bool m_illuminateLocalFeatures;
Chris@326 305 bool m_showWorkTitle;
Chris@292 306
Chris@292 307 QPalette m_lightPalette;
Chris@292 308 QPalette m_darkPalette;
Chris@127 309 };
Chris@127 310
Chris@127 311 #endif
Chris@127 312