1 // Copyright (c) 2010, Niels Martin Hansen 2 // All rights reserved. 3 // 4 // Redistribution and use in source and binary forms, with or without 5 // modification, are permitted provided that the following conditions are met: 6 // 7 // * Redistributions of source code must retain the above copyright notice, 8 // this list of conditions and the following disclaimer. 9 // * Redistributions in binary form must reproduce the above copyright notice, 10 // this list of conditions and the following disclaimer in the documentation 11 // and/or other materials provided with the distribution. 12 // * Neither the name of the Aegisub Group nor the names of its contributors 13 // may be used to endorse or promote products derived from this software 14 // without specific prior written permission. 15 // 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 20 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 // POSSIBILITY OF SUCH DAMAGE. 27 // 28 // Aegisub Project http://www.aegisub.org/ 29 30 /// @file audio_timing.h 31 /// @brief Construction-functions for timing controller objects 32 /// @ingroup audio_ui 33 34 class AssDialogue; 35 class AssFile; 36 class AssKaraoke; 37 class AudioRenderingStyleRanges; 38 namespace agi { struct Context; } 39 40 #include "audio_marker.h" 41 42 /// @class AudioTimingController 43 /// @brief Base class for objects controlling audio timing 44 /// 45 /// There is just one active audio timing controller at a time per audio 46 /// controller. The timing controller manages the timing mode and supplies 47 /// markers that can be manipulated to the audio display, as well as the 48 /// current selection. 49 /// 50 /// The timing controller must then be sent the marker drag events as well as 51 /// clicks in empty areas of the audio display. 52 class AudioTimingController : public AudioMarkerProvider, public AudioLabelProvider { 53 protected: 54 /// The primary playback range has changed, usually as a result of user interaction. 55 agi::signal::Signal<> AnnounceUpdatedPrimaryRange; 56 57 /// One or more rendering style ranges have changed in the timing controller. 58 agi::signal::Signal<> AnnounceUpdatedStyleRanges; 59 60 public: 61 /// @brief Get any warning message to show in the audio display 62 /// @return The warning message to show, may be empty if there is none 63 virtual wxString GetWarningMessage() const = 0; 64 65 /// @brief Get the time range the user is most likely to want to see for the current state 66 /// @return A time range 67 /// 68 /// This is used for "bring working area into view" operations. 69 virtual TimeRange GetIdealVisibleTimeRange() const = 0; 70 71 /// @brief Get the primary playback range 72 /// @return A time range 73 /// 74 /// Get the time range the user is most likely to want to play back 75 /// currently. 76 virtual TimeRange GetPrimaryPlaybackRange() const = 0; 77 78 /// @brief Get the active line's time 79 /// @return A time range 80 /// 81 /// Get the time range which the active line would have if any pending 82 /// modifications were committed. 83 virtual TimeRange GetActiveLineRange() const = 0; 84 85 /// @brief Get all rendering style ranges 86 /// @param[out] ranges Rendering ranges will be added to this 87 virtual void GetRenderingStyles(AudioRenderingStyleRanges &ranges) const = 0; 88 89 enum NextMode { 90 /// Advance to the next timing unit, whether it's a line or a sub-part 91 /// of a line such as a karaoke syllable 92 TIMING_UNIT = 0, 93 94 /// @brief Advance to the next line 95 /// 96 /// This may create a new line if there are no more lines in the file, 97 /// but should never modify existing lines 98 LINE, 99 100 /// @brief Advance to the next line using default timing 101 /// 102 /// This may create new lines when needed, and should discard any 103 /// existing timing data in favor of the defaults 104 LINE_RESET_DEFAULT 105 }; 106 107 /// @brief Go to next timing unit 108 /// @param mode What sort of timing unit should be advanced to 109 virtual void Next(NextMode mode) = 0; 110 111 /// @brief Go to the previous timing unit 112 /// 113 /// Rewinds the timing controller to the previous timing unit. 114 virtual void Prev() = 0; 115 116 /// @brief Commit all changes 117 /// 118 /// Stores all changes permanently. 119 virtual void Commit() = 0; 120 121 /// @brief Revert all changes 122 /// 123 /// Revert all changes to the last committed state. 124 virtual void Revert() = 0; 125 126 /// Add lead-in time to the current timing unit 127 virtual void AddLeadIn() = 0; 128 129 /// Add lead-out time to the current timing unit 130 virtual void AddLeadOut() = 0; 131 132 /// Modify the length of the current and possibly following timing units 133 /// @param delta Amount to add in centiseconds 134 /// @param shift_following Should the following things be shifted by delta? 135 virtual void ModifyLength(int delta, bool shift_following) = 0; 136 137 /// Modify the start time of the current timing unit 138 /// @param delta Amount to add in centiseconds 139 virtual void ModifyStart(int delta) = 0; 140 141 /// @brief Determine if a position is close to a draggable marker 142 /// @param ms The time in milliseconds to test 143 /// @param sensitivity Distance in milliseconds to consider markers as nearby 144 /// @return True if a marker is close by the given time, as defined by sensitivity 145 /// 146 /// This is solely for hit-testing against draggable markers, for 147 /// controlling the mouse cursor. 148 virtual bool IsNearbyMarker(int ms, int sensitivity, bool alt_down) const = 0; 149 150 /// @brief The user pressed the left mouse button on the audio 151 /// @param ms The time in milliseconds the user clicked 152 /// @param ctrl_down Is the user currently holding the ctrl key down? 153 /// @param sensitivity Distance in milliseconds to consider existing markers 154 /// @param snap_range Maximum snapping range in milliseconds 155 /// @return All audio markers at the clicked position which are eligible 156 /// to be dragged, if any. 157 virtual std::vector<AudioMarker*> OnLeftClick(int ms, bool ctrl_down, bool alt_down, int sensitivity, int snap_range) = 0; 158 159 /// @brief The user pressed the right mouse button on the audio 160 /// @param ms The time in milliseconds the user clicked 161 /// @param ctrl_down Is the user currently holding the ctrl key down? 162 /// @param sensitivity Distance in milliseconds to consider existing markers 163 /// @param snap_range Maximum snapping range in milliseconds 164 /// @return All audio markers at the clicked position which are eligible 165 /// to be dragged, if any. 166 virtual std::vector<AudioMarker*> OnRightClick(int ms, bool ctrl_down, int sensitivity, int snap_range) = 0; 167 168 /// @brief The user dragged one or more timing markers 169 /// @param marker The markers being dragged. This is guaranteed to be 170 /// a vector returned from OnLeftClick or OnRightClick. 171 /// @param new_position Time position the marker was dragged to 172 /// @param snap_range Maximum snapping range in milliseconds 173 virtual void OnMarkerDrag(std::vector<AudioMarker*> const& marker, int new_position, int snap_range) = 0; 174 175 /// @brief Destructor 176 virtual ~AudioTimingController() = default; 177 178 DEFINE_SIGNAL_ADDERS(AnnounceUpdatedPrimaryRange, AddUpdatedPrimaryRangeListener) 179 DEFINE_SIGNAL_ADDERS(AnnounceUpdatedStyleRanges, AddUpdatedStyleRangesListener) 180 }; 181 182 /// @brief Create a standard dialogue audio timing controller 183 /// @param c Project context 184 std::unique_ptr<AudioTimingController> CreateDialogueTimingController(agi::Context *c); 185 186 /// @brief Create a karaoke audio timing controller 187 /// @param c Project context 188 /// @param kara Karaoke model 189 std::unique_ptr<AudioTimingController> CreateKaraokeTimingController(agi::Context *c, AssKaraoke *kara, agi::signal::Connection& file_changed); 190