Move lead in/out logic to the timing controllers

This makes adding lead in/out work correctly when autocommit is
disabled, and improves the behavior of adding lead-in when in karaoke
mode.

Originally committed to SVN as r6502.
This commit is contained in:
Thomas Goyne 2012-02-22 22:00:54 +00:00
parent c4daf860e5
commit d5577b994c
6 changed files with 74 additions and 8 deletions

View file

@ -264,6 +264,25 @@ void AssKaraoke::SetStartTime(size_t syl_idx, int time) {
prev.duration += delta;
}
void AssKaraoke::SetLineTimes(int start_time, int end_time) {
assert(end_time >= start_time);
size_t idx = 0;
do {
int delta = start_time - syls[idx].start_time;
syls[idx].start_time = start_time;
syls[idx].duration = std::max(0, syls[idx].duration - delta);
} while (++idx < syls.size() && syls[idx].start_time < start_time);
idx = syls.size() - 1;
while (syls[idx].start_time > end_time) {
syls[idx].start_time = end_time;
syls[idx].duration = 0;
--idx;
}
syls[idx].duration = end_time - syls[idx].start_time;
}
void AssKaraoke::SplitLines(std::set<AssDialogue*> const& lines, agi::Context *c) {
if (lines.empty()) return;

View file

@ -77,6 +77,8 @@ public:
void RemoveSplit(size_t syl_idx);
/// Set the start time of a syllable in ms
void SetStartTime(size_t syl_idx, int time);
/// Adjust the line's start and end times without shifting the syllables
void SetLineTimes(int start_time, int end_time);
typedef std::vector<Syllable>::const_iterator iterator;

View file

@ -103,6 +103,12 @@ public:
/// Revert all changes to the last committed state.
virtual void Revert() = 0;
/// Add lead-in time to the current timing unit
virtual void AddLeadIn() = 0;
/// Add lead-out time to the current timing unit
virtual void AddLeadOut() = 0;
/// @brief Determine if a position is close to a draggable marker
/// @param ms The time in milliseconds to test
/// @param sensitivity Distance in milliseconds to consider markers as nearby

View file

@ -372,6 +372,8 @@ public:
void Prev();
void Commit();
void Revert();
void AddLeadIn();
void AddLeadOut();
bool IsNearbyMarker(int ms, int sensitivity) const;
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);
@ -545,6 +547,18 @@ void AudioTimingControllerDialogue::Revert()
RegenerateInactiveLines();
}
void AudioTimingControllerDialogue::AddLeadIn()
{
DialogueTimingMarker *m = active_line.GetLeftMarker();
SetMarkers(std::vector<AudioMarker*>(1, m), *m - OPT_GET("Audio/Lead/IN")->GetInt());
}
void AudioTimingControllerDialogue::AddLeadOut()
{
DialogueTimingMarker *m = active_line.GetRightMarker();
SetMarkers(std::vector<AudioMarker*>(1, m), *m + OPT_GET("Audio/Lead/OUT")->GetInt());
}
bool AudioTimingControllerDialogue::IsNearbyMarker(int ms, int sensitivity) const
{
assert(sensitivity >= 0);

View file

@ -115,6 +115,7 @@ class AudioTimingControllerKaraoke : public AudioTimingController {
void OnAutoNextChange(agi::OptionValue const& opt);
void DoCommit();
void ApplyLead(bool announce_primary);
public:
// AudioTimingController implementation
@ -128,6 +129,8 @@ public:
void Prev();
void Commit();
void Revert();
void AddLeadIn();
void AddLeadOut();
bool IsNearbyMarker(int ms, int sensitivity) const;
std::vector<AudioMarker*> OnLeftClick(int ms, bool, int sensitivity, int);
std::vector<AudioMarker*> OnRightClick(int, bool, int, int) { return std::vector<AudioMarker*>(); }
@ -279,6 +282,32 @@ void AudioTimingControllerKaraoke::Revert() {
AnnounceMarkerMoved();
}
void AudioTimingControllerKaraoke::AddLeadIn() {
start_marker.Move(start_marker - OPT_GET("Audio/Lead/IN")->GetInt());
labels.front().range = TimeRange(start_marker, labels.front().range.end());
ApplyLead(cur_syl == 0);
}
void AudioTimingControllerKaraoke::AddLeadOut() {
end_marker.Move(end_marker + OPT_GET("Audio/Lead/OUT")->GetInt());
labels.back().range = TimeRange(labels.back().range.begin(), end_marker);
ApplyLead(cur_syl == markers.size());
}
void AudioTimingControllerKaraoke::ApplyLead(bool announce_primary) {
kara->SetLineTimes(start_marker, end_marker);
AnnounceUpdatedStyleRanges();
AnnounceMarkerMoved();
if (announce_primary)
AnnounceUpdatedPrimaryRange();
if (auto_commit)
DoCommit();
else
commit_id = -1;
}
bool AudioTimingControllerKaraoke::IsNearbyMarker(int ms, int sensitivity) const {
TimeRange range(ms - sensitivity, ms + sensitivity);

View file

@ -250,10 +250,8 @@ struct time_add_lead_in : public Command {
STR_DISP("Add lead in")
STR_HELP("Add lead in")
void operator()(agi::Context *c) {
if (AssDialogue *line = c->selectionController->GetActiveLine()) {
line->Start = line->Start - OPT_GET("Audio/Lead/IN")->GetInt();
c->ass->Commit(_("add lead in"), AssFile::COMMIT_DIAG_TIME);
}
if (c->audioController->GetTimingController())
c->audioController->GetTimingController()->AddLeadIn();
}
};
@ -263,10 +261,8 @@ struct time_add_lead_out : public Command {
STR_DISP("Add lead out")
STR_HELP("Add lead out")
void operator()(agi::Context *c) {
if (AssDialogue *line = c->selectionController->GetActiveLine()) {
line->End = line->End + OPT_GET("Audio/Lead/OUT")->GetInt();
c->ass->Commit(_("add lead out"), AssFile::COMMIT_DIAG_TIME);
}
if (c->audioController->GetTimingController())
c->audioController->GetTimingController()->AddLeadOut();
}
};