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