Chris@127: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ Chris@127: Chris@127: /* Chris@127: Sonic Visualiser Chris@127: An audio file viewer and annotation editor. Chris@127: Centre for Digital Music, Queen Mary, University of London. Chris@182: This file copyright 2006 Chris Cannam and QMUL. Chris@127: Chris@127: This program is free software; you can redistribute it and/or Chris@127: modify it under the terms of the GNU General Public License as Chris@127: published by the Free Software Foundation; either version 2 of the Chris@127: License, or (at your option) any later version. See the file Chris@127: COPYING included with this distribution for more information. Chris@127: */ Chris@127: Chris@127: #ifndef _VIEW_MANAGER_H_ Chris@127: #define _VIEW_MANAGER_H_ Chris@127: Chris@127: #include Chris@127: #include Chris@292: #include Chris@127: Chris@127: #include Chris@127: Chris@376: #include "base/ViewManagerBase.h" Chris@128: #include "base/Selection.h" Chris@128: #include "base/Command.h" Chris@128: #include "base/Clipboard.h" Chris@127: Chris@127: class AudioPlaySource; Chris@127: class Model; Chris@127: Chris@211: enum PlaybackFollowMode { Chris@211: PlaybackScrollContinuous, Chris@211: PlaybackScrollPage, Chris@211: PlaybackIgnore Chris@211: }; Chris@211: Chris@211: class View; Chris@211: Chris@127: /** Chris@127: * The ViewManager manages properties that may need to be synchronised Chris@127: * between separate Views. For example, it handles signals associated Chris@127: * with changes to the global pan and zoom, and it handles selections. Chris@127: * Chris@127: * Views should be implemented in such a way as to work Chris@127: * correctly whether they are supplied with a ViewManager or not. Chris@127: */ Chris@127: Chris@376: class ViewManager : public ViewManagerBase Chris@127: { Chris@127: Q_OBJECT Chris@127: Chris@127: public: Chris@127: ViewManager(); Chris@127: virtual ~ViewManager(); Chris@127: Chris@127: void setAudioPlaySource(AudioPlaySource *source); Chris@127: Chris@127: bool isPlaying() const; Chris@127: Chris@394: unsigned long getGlobalCentreFrame() const; // the set method is a slot Chris@127: unsigned long getGlobalZoom() const; Chris@127: Chris@394: unsigned long getPlaybackFrame() const; // the set method is a slot Chris@127: Chris@301: // Only meaningful in solo mode, and used for optional alignment feature Chris@301: Model *getPlaybackModel() const; Chris@301: void setPlaybackModel(Model *); Chris@301: Chris@333: size_t alignPlaybackFrameToReference(size_t) const; Chris@333: size_t alignReferenceToPlaybackFrame(size_t) const; Chris@333: Chris@127: bool haveInProgressSelection() const; Chris@127: const Selection &getInProgressSelection(bool &exclusive) const; Chris@127: void setInProgressSelection(const Selection &selection, bool exclusive); Chris@127: void clearInProgressSelection(); Chris@127: Chris@127: const MultiSelection &getSelection() const; Chris@127: Chris@127: const MultiSelection::SelectionList &getSelections() const; Chris@127: void setSelection(const Selection &selection); Chris@127: void addSelection(const Selection &selection); Chris@127: void removeSelection(const Selection &selection); Chris@127: void clearSelections(); Chris@271: size_t constrainFrameToSelection(size_t frame) const; Chris@127: Chris@127: /** Chris@127: * Return the selection that contains a given frame. Chris@127: * If defaultToFollowing is true, and if the frame is not in a Chris@127: * selected area, return the next selection after the given frame. Chris@127: * Return the empty selection if no appropriate selection is found. Chris@127: */ Chris@127: Selection getContainingSelection(size_t frame, bool defaultToFollowing) const; Chris@127: Chris@127: Clipboard &getClipboard() { return m_clipboard; } Chris@127: Chris@127: enum ToolMode { Chris@127: NavigateMode, Chris@127: SelectMode, Chris@127: EditMode, Chris@257: DrawMode, Chris@335: EraseMode, Chris@257: MeasureMode Chris@127: }; Chris@127: ToolMode getToolMode() const { return m_toolMode; } Chris@127: void setToolMode(ToolMode mode); Chris@127: Chris@127: bool getPlayLoopMode() const { return m_playLoopMode; } Chris@127: void setPlayLoopMode(bool on); Chris@127: Chris@127: bool getPlaySelectionMode() const { return m_playSelectionMode; } Chris@127: void setPlaySelectionMode(bool on); Chris@127: Chris@301: bool getPlaySoloMode() const { return m_playSoloMode; } Chris@301: void setPlaySoloMode(bool on); Chris@301: Chris@314: bool getAlignMode() const { return m_alignMode; } Chris@314: void setAlignMode(bool on); Chris@314: Chris@326: void setIlluminateLocalFeatures(bool i) { m_illuminateLocalFeatures = i; } Chris@326: void setShowWorkTitle(bool show) { m_showWorkTitle = show; } Chris@326: Chris@224: /** Chris@224: * The sample rate that is used for playback. This is usually the Chris@224: * rate of the main model, but not always. Models whose rates Chris@224: * differ from this will play back at the wrong speed -- there is Chris@224: * no per-model resampler. Chris@224: */ Chris@127: size_t getPlaybackSampleRate() const; Chris@224: Chris@224: /** Chris@224: * The sample rate of the audio output device. If the playback Chris@224: * sample rate differs from this, everything will be resampled at Chris@224: * the output stage. Chris@224: */ Chris@224: size_t getOutputSampleRate() const; Chris@224: Chris@224: /** Chris@224: * The sample rate of the current main model. This may in theory Chris@224: * differ from the playback sample rate, in which case even the Chris@224: * main model will play at the wrong speed. Chris@224: */ Chris@127: size_t getMainModelSampleRate() const { return m_mainModelSampleRate; } Chris@224: Chris@127: void setMainModelSampleRate(size_t sr) { m_mainModelSampleRate = sr; } Chris@127: Chris@127: enum OverlayMode { Chris@127: NoOverlays, Chris@189: MinimalOverlays, Chris@189: StandardOverlays, Chris@127: AllOverlays Chris@127: }; Chris@127: void setOverlayMode(OverlayMode mode); Chris@127: OverlayMode getOverlayMode() const { return m_overlayMode; } Chris@127: Chris@189: bool shouldShowCentreLine() const { Chris@189: return m_overlayMode != NoOverlays; Chris@189: } Chris@189: bool shouldShowFrameCount() const { Chris@189: return m_overlayMode != NoOverlays; Chris@189: } Chris@189: bool shouldShowDuration() const { Chris@189: return m_overlayMode > MinimalOverlays; Chris@189: } Chris@189: bool shouldShowVerticalScale() const { Chris@189: return m_overlayMode > MinimalOverlays; Chris@189: } Chris@189: bool shouldShowSelectionExtents() const { Chris@189: return m_overlayMode > MinimalOverlays; Chris@189: } Chris@189: bool shouldShowLayerNames() const { Chris@189: return m_overlayMode == AllOverlays; Chris@189: } Chris@195: bool shouldShowScaleGuides() const { Chris@195: return m_overlayMode != NoOverlays; Chris@195: } Chris@326: bool shouldShowWorkTitle() const { Chris@326: return m_showWorkTitle; Chris@326: } Chris@326: bool shouldIlluminateLocalFeatures() const { Chris@326: return m_illuminateLocalFeatures; Chris@326: } Chris@189: Chris@133: void setZoomWheelsEnabled(bool enable); Chris@133: bool getZoomWheelsEnabled() const { return m_zoomWheelsEnabled; } Chris@133: Chris@292: void setGlobalDarkBackground(bool dark); Chris@292: bool getGlobalDarkBackground() const; Chris@292: mathieu@588: void setMinimalModeEnabled(bool enable); mathieu@588: bool getMinimalModeEnabled() const { return m_minimalModeEnabled; }; mathieu@588: Chris@127: signals: Chris@211: /** Emitted when user causes the global centre frame to change. */ Chris@211: void globalCentreFrameChanged(unsigned long frame); Chris@127: Chris@211: /** Emitted when user scrolls a view, but doesn't affect global centre. */ Chris@211: void viewCentreFrameChanged(View *v, unsigned long frame); Chris@211: Chris@211: /** Emitted when a view zooms. */ Chris@222: void viewZoomLevelChanged(View *v, unsigned long zoom, bool locked); Chris@133: Chris@127: /** Emitted when the playback frame changes. */ Chris@127: void playbackFrameChanged(unsigned long frame); Chris@127: Chris@127: /** Emitted when the output levels change. Values in range 0.0 -> 1.0. */ Chris@127: void outputLevelsChanged(float left, float right); Chris@127: Chris@127: /** Emitted when the selection has changed. */ Chris@127: void selectionChanged(); Chris@127: Chris@127: /** Emitted when the in-progress (rubberbanding) selection has changed. */ Chris@127: void inProgressSelectionChanged(); Chris@127: Chris@127: /** Emitted when the tool mode has been changed. */ Chris@127: void toolModeChanged(); Chris@127: Chris@127: /** Emitted when the play loop mode has been changed. */ Chris@127: void playLoopModeChanged(); Chris@177: void playLoopModeChanged(bool); Chris@127: Chris@127: /** Emitted when the play selection mode has been changed. */ Chris@127: void playSelectionModeChanged(); Chris@177: void playSelectionModeChanged(bool); Chris@127: Chris@301: /** Emitted when the play solo mode has been changed. */ Chris@301: void playSoloModeChanged(); Chris@301: void playSoloModeChanged(bool); Chris@301: Chris@314: /** Emitted when the alignment mode has been changed. */ Chris@314: void alignModeChanged(); Chris@314: void alignModeChanged(bool); Chris@314: Chris@127: /** Emitted when the overlay mode has been changed. */ Chris@127: void overlayModeChanged(); Chris@127: Chris@133: /** Emitted when the zoom wheels have been toggled. */ Chris@133: void zoomWheelsEnabledChanged(); Chris@133: Chris@502: /** Emitted when any loggable activity has occurred. */ Chris@502: void activity(QString); Chris@502: mathieu@588: /** Emitted when the view mode has been toggled. */ mathieu@588: //no slot associated yet with this signal but may be useful; mathieu@588: //changes currently handled by the slot MainWindow::toggleViewMode() mathieu@588: void minimalModeEnabledChanged(); mathieu@588: Chris@211: public slots: Chris@211: void viewCentreFrameChanged(unsigned long, bool, PlaybackFollowMode); Chris@222: void viewZoomLevelChanged(unsigned long, bool); Chris@394: void setGlobalCentreFrame(unsigned long); Chris@394: void setPlaybackFrame(unsigned long); Chris@591: void playExampleNote(int midiPitch); Chris@211: Chris@127: protected slots: Chris@127: void checkPlayStatus(); Chris@127: void playStatusChanged(bool playing); Chris@211: void seek(unsigned long); Chris@222: //!!! void considerZoomChange(void *, unsigned long, bool); Chris@127: Chris@127: protected: Chris@127: AudioPlaySource *m_playSource; Chris@127: unsigned long m_globalCentreFrame; Chris@127: unsigned long m_globalZoom; Chris@127: mutable unsigned long m_playbackFrame; Chris@301: Model *m_playbackModel; //!!! Chris@127: size_t m_mainModelSampleRate; Chris@127: Chris@127: float m_lastLeft; Chris@127: float m_lastRight; Chris@127: Chris@127: MultiSelection m_selections; Chris@127: Selection m_inProgressSelection; Chris@127: bool m_inProgressExclusive; Chris@127: Chris@127: Clipboard m_clipboard; Chris@127: Chris@127: ToolMode m_toolMode; Chris@127: Chris@127: bool m_playLoopMode; Chris@127: bool m_playSelectionMode; Chris@301: bool m_playSoloMode; Chris@314: bool m_alignMode; Chris@127: Chris@127: void setSelections(const MultiSelection &ms); Chris@127: void signalSelectionChange(); Chris@127: Chris@127: class SetSelectionCommand : public Command Chris@127: { Chris@127: public: Chris@127: SetSelectionCommand(ViewManager *vm, const MultiSelection &ms); Chris@127: virtual ~SetSelectionCommand(); Chris@127: virtual void execute(); Chris@127: virtual void unexecute(); Chris@127: virtual QString getName() const; Chris@127: Chris@127: protected: Chris@127: ViewManager *m_vm; Chris@127: MultiSelection m_oldSelection; Chris@127: MultiSelection m_newSelection; Chris@127: }; Chris@127: Chris@127: OverlayMode m_overlayMode; Chris@133: bool m_zoomWheelsEnabled; Chris@326: bool m_illuminateLocalFeatures; Chris@326: bool m_showWorkTitle; Chris@292: mathieu@588: bool m_minimalModeEnabled; mathieu@588: Chris@292: QPalette m_lightPalette; Chris@292: QPalette m_darkPalette; Chris@127: }; Chris@127: Chris@127: #endif Chris@127: