Modify the TimingController interface to support dragging more than one marker at once. Updates #20.
Originally committed to SVN as r6460.
This commit is contained in:
parent
51a3831794
commit
32c8cc0974
4 changed files with 48 additions and 42 deletions
|
@ -464,7 +464,7 @@ public:
|
|||
|
||||
class AudioMarkerInteractionObject : public AudioDisplayInteractionObject {
|
||||
// Object-pair being interacted with
|
||||
AudioMarker *marker;
|
||||
std::vector<AudioMarker*> markers;
|
||||
AudioTimingController *timing_controller;
|
||||
// Audio display drag is happening on
|
||||
AudioDisplay *display;
|
||||
|
@ -478,8 +478,8 @@ class AudioMarkerInteractionObject : public AudioDisplayInteractionObject {
|
|||
int snap_range;
|
||||
|
||||
public:
|
||||
AudioMarkerInteractionObject(AudioMarker *marker, AudioTimingController *timing_controller, AudioDisplay *display, AudioController *controller, wxMouseButton button_used)
|
||||
: marker(marker)
|
||||
AudioMarkerInteractionObject(std::vector<AudioMarker*> markers, AudioTimingController *timing_controller, AudioDisplay *display, AudioController *controller, wxMouseButton button_used)
|
||||
: markers(markers)
|
||||
, timing_controller(timing_controller)
|
||||
, display(display)
|
||||
, controller(controller)
|
||||
|
@ -494,7 +494,7 @@ public:
|
|||
if (event.Dragging())
|
||||
{
|
||||
timing_controller->OnMarkerDrag(
|
||||
marker,
|
||||
markers,
|
||||
display->TimeFromRelativeX(event.GetPosition().x),
|
||||
default_snap != event.ShiftDown() ? display->TimeFromAbsoluteX(snap_range) : 0);
|
||||
}
|
||||
|
@ -1093,14 +1093,14 @@ void AudioDisplay::OnMouseEvent(wxMouseEvent& event)
|
|||
if (event.LeftDown() || event.RightDown())
|
||||
{
|
||||
int timepos = TimeFromRelativeX(mousepos.x);
|
||||
AudioMarker *marker = event.LeftDown() ?
|
||||
timing->OnLeftClick(timepos, drag_sensitivity, snap_sensitivity) :
|
||||
timing->OnRightClick(timepos, drag_sensitivity, snap_sensitivity);
|
||||
std::vector<AudioMarker*> markers = event.LeftDown() ?
|
||||
timing->OnLeftClick(timepos, event.CmdDown(), drag_sensitivity, snap_sensitivity) :
|
||||
timing->OnRightClick(timepos, event.CmdDown(), drag_sensitivity, snap_sensitivity);
|
||||
|
||||
if (marker)
|
||||
if (markers.size())
|
||||
{
|
||||
RemoveTrackCursor();
|
||||
audio_marker.reset(new AudioMarkerInteractionObject(marker, timing, this, controller, (wxMouseButton)event.GetButton()));
|
||||
audio_marker.reset(new AudioMarkerInteractionObject(markers, timing, this, controller, (wxMouseButton)event.GetButton()));
|
||||
SetDraggedObject(audio_marker.get());
|
||||
return;
|
||||
}
|
||||
|
@ -1173,6 +1173,8 @@ void AudioDisplay::OnAudioOpen(AudioProvider *provider)
|
|||
connections.push_back(OPT_SUB("Colour/Audio Display/Spectrum", &AudioDisplay::ReloadRenderingSettings, this));
|
||||
connections.push_back(OPT_SUB("Colour/Audio Display/Waveform", &AudioDisplay::ReloadRenderingSettings, this));
|
||||
connections.push_back(OPT_SUB("Audio/Renderer/Spectrum/Quality", &AudioDisplay::ReloadRenderingSettings, this));
|
||||
|
||||
OnTimingController();
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -112,29 +112,30 @@ public:
|
|||
/// controlling the mouse cursor.
|
||||
virtual bool IsNearbyMarker(int ms, int sensitivity) const = 0;
|
||||
|
||||
/// @brief The user pressed the left button down at an empty place in the audio
|
||||
/// @brief The user pressed the left mouse button on the audio
|
||||
/// @param ms The time in milliseconds the user clicked
|
||||
/// @param ctrl_down Is the user currently holding the ctrl key down?
|
||||
/// @param sensitivity Distance in milliseconds to consider existing markers
|
||||
/// @param snap_range Maximum snapping range in milliseconds
|
||||
/// @return An audio marker or 0. If a marker is returned and the user
|
||||
/// starts dragging the mouse after pressing down the button, the returned
|
||||
/// marker is being dragged.
|
||||
virtual AudioMarker * OnLeftClick(int ms, int sensitivity, int snap_range) = 0;
|
||||
/// @return All audio markers at the clicked position which are eligible
|
||||
/// to be dragged, if any.
|
||||
virtual std::vector<AudioMarker*> OnLeftClick(int ms, bool ctrl_down, int sensitivity, int snap_range) = 0;
|
||||
|
||||
/// @brief The user pressed the right button down at an empty place in the audio
|
||||
/// @brief The user pressed the right mouse button on the audio
|
||||
/// @param ms The time in milliseconds the user clicked
|
||||
/// @param ctrl_down Is the user currently holding the ctrl key down?
|
||||
/// @param sensitivity Distance in milliseconds to consider existing markers
|
||||
/// @param snap_range Maximum snapping range in milliseconds
|
||||
/// @return An audio marker or 0. If a marker is returned and the user
|
||||
/// starts dragging the mouse after pressing down the button, the returned
|
||||
/// marker is being dragged.
|
||||
virtual AudioMarker * OnRightClick(int ms, int sensitivity, int snap_range) = 0;
|
||||
/// @return All audio markers at the clicked position which are eligible
|
||||
/// to be dragged, if any.
|
||||
virtual std::vector<AudioMarker*> OnRightClick(int ms, bool ctrl_down, int sensitivity, int snap_range) = 0;
|
||||
|
||||
/// @brief The user dragged a timing marker
|
||||
/// @param marker The marker being dragged
|
||||
/// @brief The user dragged one or more timing markers
|
||||
/// @param marker The markers being dragged. This is guaranteed to be
|
||||
/// a vector returned from OnLeftClick or OnRightClick.
|
||||
/// @param new_position Time position the marker was dragged to
|
||||
/// @param snap_range Maximum snapping range in milliseconds
|
||||
virtual void OnMarkerDrag(AudioMarker *marker, int new_position, int snap_range) = 0;
|
||||
/// @param snap_range Maximum snapping range in milliseconds
|
||||
virtual void OnMarkerDrag(std::vector<AudioMarker*> const& marker, int new_position, int snap_range) = 0;
|
||||
|
||||
/// @brief Destructor
|
||||
virtual ~AudioTimingController() { }
|
||||
|
|
|
@ -231,9 +231,9 @@ public:
|
|||
void Commit();
|
||||
void Revert();
|
||||
bool IsNearbyMarker(int ms, int sensitivity) const;
|
||||
AudioMarker * OnLeftClick(int ms, int sensitivity, int snap_range);
|
||||
AudioMarker * OnRightClick(int ms, int sensitivity, int snap_range);
|
||||
void OnMarkerDrag(AudioMarker *marker, int new_position, int snap_range);
|
||||
std::vector<AudioMarker*> OnLeftClick(int ms, bool ctrl_down, int sensitivity, int snap_range);
|
||||
std::vector<AudioMarker*> OnRightClick(int ms, bool, int sensitivity, int snap_range);
|
||||
void OnMarkerDrag(std::vector<AudioMarker*> const& markers, int new_position, int snap_range);
|
||||
|
||||
public:
|
||||
// Specific interface
|
||||
|
@ -494,7 +494,7 @@ bool AudioTimingControllerDialogue::IsNearbyMarker(int ms, int sensitivity) cons
|
|||
return range.contains(active_markers[0]) || range.contains(active_markers[1]);
|
||||
}
|
||||
|
||||
AudioMarker * AudioTimingControllerDialogue::OnLeftClick(int ms, int sensitivity, int snap_range)
|
||||
std::vector<AudioMarker*> AudioTimingControllerDialogue::OnLeftClick(int ms, bool ctrl_down, int sensitivity, int snap_range)
|
||||
{
|
||||
assert(sensitivity >= 0);
|
||||
|
||||
|
@ -511,32 +511,34 @@ AudioMarker * AudioTimingControllerDialogue::OnLeftClick(int ms, int sensitivity
|
|||
// Clicked near the left marker:
|
||||
// Insta-move it and start dragging it
|
||||
SetMarker(left, SnapPosition(ms, snap_range));
|
||||
return left;
|
||||
return std::vector<AudioMarker*>(1, left);
|
||||
}
|
||||
|
||||
if (dist_r < dist_l && dist_r <= sensitivity)
|
||||
{
|
||||
// Clicked near the right marker:
|
||||
// Only drag it. For insta-move, the user must right-click.
|
||||
return right;
|
||||
return std::vector<AudioMarker*>(1, right);
|
||||
}
|
||||
|
||||
// Clicked far from either marker:
|
||||
// Insta-set the left marker to the clicked position and return the right as the dragged one,
|
||||
// such that if the user does start dragging, he will create a new selection from scratch
|
||||
SetMarker(left, SnapPosition(ms, snap_range));
|
||||
return right;
|
||||
return std::vector<AudioMarker*>(1, right);
|
||||
}
|
||||
|
||||
AudioMarker * AudioTimingControllerDialogue::OnRightClick(int ms, int sensitivity, int snap_range)
|
||||
std::vector<AudioMarker*> AudioTimingControllerDialogue::OnRightClick(int ms, bool, int sensitivity, int snap_range)
|
||||
{
|
||||
AudioMarkerDialogueTiming *right = GetRightMarker();
|
||||
SetMarker(right, SnapPosition(ms, snap_range));
|
||||
return right;
|
||||
return std::vector<AudioMarker*>(1, right);
|
||||
}
|
||||
|
||||
void AudioTimingControllerDialogue::OnMarkerDrag(AudioMarker *marker, int new_position, int snap_range)
|
||||
void AudioTimingControllerDialogue::OnMarkerDrag(std::vector<AudioMarker*> const& markers, int new_position, int snap_range)
|
||||
{
|
||||
assert(markers.size() == 1);
|
||||
AudioMarker *marker = markers[0];
|
||||
assert(marker == &active_markers[0] || marker == &active_markers[1]);
|
||||
|
||||
SetMarker(static_cast<AudioMarkerDialogueTiming*>(marker), SnapPosition(new_position, snap_range));
|
||||
|
|
|
@ -129,9 +129,9 @@ public:
|
|||
void Commit();
|
||||
void Revert();
|
||||
bool IsNearbyMarker(int ms, int sensitivity) const;
|
||||
AudioMarker * OnLeftClick(int ms, int sensitivity, int);
|
||||
AudioMarker * OnRightClick(int, int, int) { return 0; }
|
||||
void OnMarkerDrag(AudioMarker *marker, int new_position, int);
|
||||
std::vector<AudioMarker*> OnLeftClick(int ms, bool, int sensitivity, int);
|
||||
std::vector<AudioMarker*> OnRightClick(int, bool, int, int) { return std::vector<AudioMarker*>(); }
|
||||
void OnMarkerDrag(std::vector<AudioMarker*> const& marker, int new_position, int);
|
||||
|
||||
AudioTimingControllerKaraoke(agi::Context *c, AssKaraoke *kara, agi::signal::Connection& file_changed);
|
||||
};
|
||||
|
@ -289,25 +289,26 @@ bool AudioTimingControllerKaraoke::IsNearbyMarker(int ms, int sensitivity) const
|
|||
return false;
|
||||
}
|
||||
|
||||
AudioMarker *AudioTimingControllerKaraoke::OnLeftClick(int ms, int sensitivity, int) {
|
||||
std::vector<AudioMarker*> AudioTimingControllerKaraoke::OnLeftClick(int ms, bool, int sensitivity, int) {
|
||||
TimeRange range(ms - sensitivity, ms + sensitivity);
|
||||
|
||||
size_t syl = distance(markers.begin(), lower_bound(markers.begin(), markers.end(), ms));
|
||||
if (syl < markers.size() && range.contains(markers[syl]))
|
||||
return &markers[syl];
|
||||
return std::vector<AudioMarker*>(1, &markers[syl]);
|
||||
if (syl > 0 && range.contains(markers[syl - 1]))
|
||||
return &markers[syl - 1];
|
||||
return std::vector<AudioMarker*>(1, &markers[syl - 1]);
|
||||
|
||||
cur_syl = syl;
|
||||
|
||||
AnnounceUpdatedPrimaryRange();
|
||||
AnnounceUpdatedStyleRanges();
|
||||
|
||||
return 0;
|
||||
return std::vector<AudioMarker*>();
|
||||
}
|
||||
|
||||
void AudioTimingControllerKaraoke::OnMarkerDrag(AudioMarker *m, int new_position, int) {
|
||||
KaraokeMarker *marker = static_cast<KaraokeMarker*>(m);
|
||||
void AudioTimingControllerKaraoke::OnMarkerDrag(std::vector<AudioMarker*> const& m, int new_position, int) {
|
||||
assert(m.size() == 1);
|
||||
KaraokeMarker *marker = static_cast<KaraokeMarker*>(m[0]);
|
||||
// No rearranging of syllables allowed
|
||||
new_position = mid(
|
||||
marker == &markers.front() ? start_marker.GetPosition() : (marker - 1)->GetPosition(),
|
||||
|
|
Loading…
Reference in a new issue