Some clean up to audio display code, added option to show/hide keyframes on audio display, and individual options to automatically snap to keyframes and adjascent lines (behavior can always be toggled by holding down shift).

Originally committed to SVN as r1016.
This commit is contained in:
Rodrigo Braz Monteiro 2007-04-07 02:39:18 +00:00
parent 7e040f6a66
commit 263df94e69
5 changed files with 138 additions and 101 deletions

View File

@ -159,8 +159,10 @@ void AudioDisplay::UpdateImage(bool weak) {
}
}
// Options
bool draw_boundary_lines = Options.AsBool(_T("Audio Draw Secondary Lines"));
bool draw_selection_background = Options.AsBool(_T("Audio Draw Selection Background"));
bool drawKeyframes = Options.AsBool(_T("Audio Draw Keyframes"));
// Invalid dimensions
if (w == 0 || displayH == 0) return;
@ -227,6 +229,16 @@ void AudioDisplay::UpdateImage(bool weak) {
DrawSpectrum(dc,weak);
}
// Waveform
else if (provider) {
DrawWaveform(dc,weak);
}
// Nothing
else {
dc.DrawLine(0,h/2,w,h/2);
}
// Draw seconds boundaries
if (draw_boundary_lines) {
__int64 start = Position*samples;
@ -243,34 +255,8 @@ void AudioDisplay::UpdateImage(bool weak) {
}
// Draw keyframes
if (VideoContext::Get()->KeyFramesLoaded() && draw_boundary_lines) {
wxArrayInt KeyFrames = VideoContext::Get()->GetKeyFrames();
int nKeys = (int)KeyFrames.Count();
dc.SetPen(wxPen(wxColour(255,0,255),1));
// Get min and max frames to care about
int minFrame = VFR_Output.GetFrameAtTime(GetMSAtX(0),true);
int maxFrame = VFR_Output.GetFrameAtTime(GetMSAtX(w),true);
// Scan list
for (int i=0;i<nKeys;i++) {
int cur = KeyFrames[i];
if (cur >= minFrame && cur <= maxFrame) {
int x = GetXAtMS(VFR_Output.GetTimeAtFrame(cur,true));
dc.DrawLine(x,0,x,h);
}
else if (cur > maxFrame) break;
}
}
// Waveform
if (provider) {
if (!spectrum) DrawWaveform(dc,weak);
}
// Nothing
else {
dc.DrawLine(0,h/2,w,h/2);
if (drawKeyframes && VideoContext::Get()->KeyFramesLoaded()) {
DrawKeyframes(dc);
}
// Draw previous line
@ -397,6 +383,11 @@ void AudioDisplay::UpdateImage(bool weak) {
}
}
// Draw timescale
if (timelineHeight) {
DrawTimescale(dc);
}
// Draw selection border
if (hasFocus) {
dc.SetPen(*wxGREEN_PEN);
@ -404,70 +395,99 @@ void AudioDisplay::UpdateImage(bool weak) {
dc.DrawRectangle(0,0,w,h);
}
// Draw timescale
if (timelineHeight) {
dc.SetBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE));
dc.SetPen(*wxTRANSPARENT_PEN);
dc.DrawRectangle(0,h,w,timelineHeight);
dc.SetPen(wxSystemSettings::GetColour(wxSYS_COLOUR_3DLIGHT));
dc.DrawLine(0,h,w,h);
dc.SetPen(wxSystemSettings::GetColour(wxSYS_COLOUR_3DHIGHLIGHT));
dc.DrawLine(0,h+1,w,h+1);
dc.SetPen(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT));
dc.SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT));
wxFont scaleFont;
scaleFont.SetFaceName(_T("Tahoma")); // FIXME: hardcoded font name
scaleFont.SetPointSize(8);
dc.SetFont(scaleFont);
// Timescale ticks
__int64 start = Position*samples;
int rate = provider->GetSampleRate();
for (int i=1;i<32;i*=2) {
int pixBounds = rate / (samples * 4 / i);
if (pixBounds >= 8) {
for (int x=0;x<w;x++) {
__int64 pos = (x*samples)+start;
// Second boundary
if (pos % rate < samples) {
dc.DrawLine(x,h+2,x,h+8);
// Draw text
wxCoord textW,textH;
int hr = 0;
int m = 0;
int s = pos/rate;
while (s >= 3600) {
s -= 3600;
hr++;
}
while (s >= 60) {
s -= 60;
m++;
}
wxString text;
if (hr) text = wxString::Format(_T("%i:%02i:%02i"),hr,m,s);
else if (m) text = wxString::Format(_T("%i:%02i"),m,s);
else text = wxString::Format(_T("%i"),s);
dc.GetTextExtent(text,&textW,&textH,NULL,NULL,&scaleFont);
dc.DrawText(text,MAX(0,x-textW/2)+1,h+8);
}
// Other
else if (pos % (rate / 4 * i) < samples) {
dc.DrawLine(x,h+2,x,h+5);
}
}
break;
}
}
}
// Done
Refresh(false);
}
//////////////////
// Draw keyframes
void AudioDisplay::DrawKeyframes(wxDC &dc) {
wxArrayInt KeyFrames = VideoContext::Get()->GetKeyFrames();
int nKeys = (int)KeyFrames.Count();
dc.SetPen(wxPen(wxColour(255,0,255),1));
// Get min and max frames to care about
int minFrame = VFR_Output.GetFrameAtTime(GetMSAtX(0),true);
int maxFrame = VFR_Output.GetFrameAtTime(GetMSAtX(w),true);
// Scan list
for (int i=0;i<nKeys;i++) {
int cur = KeyFrames[i];
if (cur >= minFrame && cur <= maxFrame) {
int x = GetXAtMS(VFR_Output.GetTimeAtFrame(cur,true));
dc.DrawLine(x,0,x,h);
}
else if (cur > maxFrame) break;
}
}
//////////////////
// Draw timescale
void AudioDisplay::DrawTimescale(wxDC &dc) {
// Set size
int timelineHeight = Options.AsBool(_T("Audio Draw Timeline")) ? 20 : 0;
// Set colours
dc.SetBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE));
dc.SetPen(*wxTRANSPARENT_PEN);
dc.DrawRectangle(0,h,w,timelineHeight);
dc.SetPen(wxSystemSettings::GetColour(wxSYS_COLOUR_3DLIGHT));
dc.DrawLine(0,h,w,h);
dc.SetPen(wxSystemSettings::GetColour(wxSYS_COLOUR_3DHIGHLIGHT));
dc.DrawLine(0,h+1,w,h+1);
dc.SetPen(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT));
dc.SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT));
wxFont scaleFont;
scaleFont.SetFaceName(_T("Tahoma")); // FIXME: hardcoded font name
scaleFont.SetPointSize(8);
dc.SetFont(scaleFont);
// Timescale ticks
__int64 start = Position*samples;
int rate = provider->GetSampleRate();
for (int i=1;i<32;i*=2) {
int pixBounds = rate / (samples * 4 / i);
if (pixBounds >= 8) {
for (int x=0;x<w;x++) {
__int64 pos = (x*samples)+start;
// Second boundary
if (pos % rate < samples) {
dc.DrawLine(x,h+2,x,h+8);
// Draw text
wxCoord textW,textH;
int hr = 0;
int m = 0;
int s = pos/rate;
while (s >= 3600) {
s -= 3600;
hr++;
}
while (s >= 60) {
s -= 60;
m++;
}
wxString text;
if (hr) text = wxString::Format(_T("%i:%02i:%02i"),hr,m,s);
else if (m) text = wxString::Format(_T("%i:%02i"),m,s);
else text = wxString::Format(_T("%i"),s);
dc.GetTextExtent(text,&textW,&textH,NULL,NULL,&scaleFont);
dc.DrawText(text,MAX(0,x-textW/2)+1,h+8);
}
// Other
else if (pos % (rate / 4 * i) < samples) {
dc.DrawLine(x,h+2,x,h+5);
}
}
break;
}
}
}
////////////
// Waveform
void AudioDisplay::DrawWaveform(wxDC &dc,bool weak) {
@ -1372,7 +1392,7 @@ void AudioDisplay::OnMouseEvent(wxMouseEvent& event) {
if (leftIsDown && x != lastX) {
selStart = lastX;
selEnd = x;
curStartMS = GetBoundarySnap(GetMSAtX(lastX),event.ShiftDown()?0:10,true);
curStartMS = GetBoundarySnap(GetMSAtX(lastX),10,event.ShiftDown(),true);
curEndMS = GetMSAtX(x);
hold = 2;
}
@ -1383,7 +1403,7 @@ void AudioDisplay::OnMouseEvent(wxMouseEvent& event) {
if (hold == 1 && buttonIsDown) {
// Set new value
if (x != selStart) {
int snapped = GetBoundarySnap(GetMSAtX(x),event.ShiftDown()?0:10,true);
int snapped = GetBoundarySnap(GetMSAtX(x),10,event.ShiftDown(),true);
selStart = GetXAtMS(snapped);
if (selStart > selEnd) {
int temp = selStart;
@ -1403,7 +1423,7 @@ void AudioDisplay::OnMouseEvent(wxMouseEvent& event) {
if (hold == 2 && buttonIsDown) {
// Set new value
if (x != selEnd) {
int snapped = GetBoundarySnap(GetMSAtX(x),event.ShiftDown()?0:10,false);
int snapped = GetBoundarySnap(GetMSAtX(x),10,event.ShiftDown(),false);
selEnd = GetXAtMS(snapped);
//selEnd = GetBoundarySnap(x,event.ShiftDown()?0:10,false);
if (selStart > selEnd) {
@ -1496,16 +1516,18 @@ void AudioDisplay::OnMouseEvent(wxMouseEvent& event) {
////////////////////////
// Get snap to boundary
int AudioDisplay::GetBoundarySnap(int ms,int rangeX,bool start) {
int AudioDisplay::GetBoundarySnap(int ms,int rangeX,bool shiftHeld,bool start) {
// Range?
if (rangeX <= 0) return ms;
// Convert range into miliseconds
int rangeMS = rangeX*samples*1000 / provider->GetSampleRate();
// Find the snap boundaries
// Keyframe boundaries
wxArrayInt boundaries;
if (VideoContext::Get()->KeyFramesLoaded() && Options.AsBool(_T("Audio Draw Secondary Lines"))) {
bool snapKey = Options.AsBool(_T("Audio snap to keyframes"));
if (shiftHeld) snapKey = !snapKey;
if (snapKey && VideoContext::Get()->KeyFramesLoaded() && Options.AsBool(_T("Audio Draw Keyframes"))) {
__int64 keyMS;
wxArrayInt keyFrames = VideoContext::Get()->GetKeyFrames();
int frame;
@ -1521,7 +1543,9 @@ int AudioDisplay::GetBoundarySnap(int ms,int rangeX,bool start) {
// Other subtitles' boundaries
int inactiveType = Options.AsInt(_T("Audio Inactive Lines Display Mode"));
if (inactiveType == 1 || inactiveType == 2) {
bool snapLines = Options.AsBool(_T("Audio snap to other lines"));
if (shiftHeld) snapLines = !snapLines;
if (snapLines && (inactiveType == 1 || inactiveType == 2)) {
AssDialogue *shade;
int shadeX1,shadeX2;
int shadeFrom,shadeTo;

View File

@ -117,13 +117,15 @@ private:
void UpdateSamples();
void Reset();
void DrawTimescale(wxDC &dc);
void DrawKeyframes(wxDC &dc);
void DrawWaveform(wxDC &dc,bool weak);
void DrawSpectrum(wxDC &dc,bool weak);
void GetDialoguePos(__int64 &start,__int64 &end,bool cap);
void GetKaraokePos(__int64 &start,__int64 &end,bool cap);
void UpdatePosition(int pos,bool IsSample=false);
int GetBoundarySnap(int x,int range,bool start=true);
int GetBoundarySnap(int x,int range,bool shiftHeld,bool start=true);
public:
AudioProvider *provider;

View File

@ -388,7 +388,7 @@ DialogOptions::DialogOptions(wxWindow *parent)
wxSizer *audioMainSizer = new wxBoxSizer(wxVERTICAL);
wxSizer *audioSizer1 = new wxStaticBoxSizer(wxVERTICAL,audioPage,_("Options"));
wxSizer *audioSizer2 = new wxStaticBoxSizer(wxVERTICAL,audioPage,_("Advanced - EXPERT USERS ONLY"));
wxFlexGridSizer *audioSizer3 = new wxFlexGridSizer(2,2,5,5);
wxFlexGridSizer *audioSizer3 = new wxFlexGridSizer(3,2,5,5);
wxFlexGridSizer *audioSizer4 = new wxFlexGridSizer(4,2,5,5);
wxFlexGridSizer *audioSizer5 = new wxFlexGridSizer(4,2,5,5);
wxControl *control;
@ -406,6 +406,12 @@ DialogOptions::DialogOptions(wxWindow *parent)
control = new wxCheckBox(audioPage,-1,_("Lock scroll on Cursor"));
Bind(control,_T("Audio lock scroll on cursor"));
audioSizer3->Add(control,1,wxEXPAND,0);
control = new wxCheckBox(audioPage,-1,_("Snap to keyframes"));
Bind(control,_T("Audio snap to keyframes"));
audioSizer3->Add(control,1,wxEXPAND,0);
control = new wxCheckBox(audioPage,-1,_("Snap to adjascent lines"));
Bind(control,_T("Audio snap to other lines"));
audioSizer3->Add(control,1,wxEXPAND,0);
audioSizer3->AddGrowableCol(0,1);
// Second sizer
@ -475,13 +481,15 @@ DialogOptions::DialogOptions(wxWindow *parent)
wxSizer *displayMainSizer = new wxBoxSizer(wxVERTICAL);
wxSizer *displaySizer1 = new wxStaticBoxSizer(wxVERTICAL,displayPage,_("Options"));
wxSizer *displaySizer2 = new wxStaticBoxSizer(wxVERTICAL,displayPage,_("Style"));
wxFlexGridSizer *displaySizer3 = new wxFlexGridSizer(2,2,2,2);
wxFlexGridSizer *displaySizer3 = new wxFlexGridSizer(3,2,2,2);
wxFlexGridSizer *displaySizer4 = new wxFlexGridSizer(14,2,2,2);
// First sizer
wxString labels1[4] = { _("Draw secondary lines"), _("Draw selection background"), _("Draw timeline"), _("Draw cursor time") };
wxString options1[4] = { _T("Draw Secondary Lines"), _T("Draw Selection Background") , _T("Draw Timeline"), _T("Draw Cursor Time")};
for (int i=0;i<4;i++) {
wxString labels1[5] = { _("Draw secondary lines"), _("Draw selection background"), _("Draw timeline"),
_("Draw cursor time"), _("Draw keyframes") };
wxString options1[5] = { _T("Draw Secondary Lines"), _T("Draw Selection Background") , _T("Draw Timeline"),
_T("Draw Cursor Time"), _T("Draw keyframes")};
for (int i=0;i<5;i++) {
wxCheckBox *control = new wxCheckBox(displayPage,-1,labels1[i]);
Bind(control,_T("Audio ") + options1[i]);
displaySizer3->Add(control,1,wxEXPAND | wxALL,5);

View File

@ -163,6 +163,8 @@ void OptionsManager::LoadDefaults() {
SetBool(_T("Audio Autofocus"),false);
SetBool(_T("Audio Wheel Default To Zoom"),false);
SetBool(_T("Audio lock scroll on cursor"),false);
SetBool(_T("Audio snap to keyframes"),false);
SetBool(_T("Audio snap to other lines"),false);
SetInt(_T("Timing Default Duration"), 2000);
SetInt(_T("Audio lead in"),200);
SetInt(_T("Audio lead out"),300);
@ -235,6 +237,7 @@ void OptionsManager::LoadDefaults() {
SetInt(_T("Audio Line boundaries Thickness"), 2);
SetBool(_T("Audio Draw Secondary Lines"), true);
SetBool(_T("Audio Draw Selection Background"), true);
SetBool(_T("Audio Draw Keyframes"), true);
SetBool(_T("Audio Draw Timeline"),true);
SetBool(_T("Audio Draw Cursor Time"),true);
SetColour(_T("Audio Selection Background Modified"),wxColour(92,0,0));

View File

@ -40,7 +40,7 @@
#include "ass_file.h"
#include "video_context.h"
#ifdef WIN32
#define CSRIAPI __declspec(dllimport)
#define CSRIAPI
#endif
#include "csri/csri.h"