diff --git a/aegisub/audio_display.cpp b/aegisub/audio_display.cpp index 0b88bed66..dd92b9572 100644 --- a/aegisub/audio_display.cpp +++ b/aegisub/audio_display.cpp @@ -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= 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= 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= 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= 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; diff --git a/aegisub/audio_display.h b/aegisub/audio_display.h index b934da06c..17e9aee56 100644 --- a/aegisub/audio_display.h +++ b/aegisub/audio_display.h @@ -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; diff --git a/aegisub/dialog_options.cpp b/aegisub/dialog_options.cpp index 2cd34976f..3f97d707d 100644 --- a/aegisub/dialog_options.cpp +++ b/aegisub/dialog_options.cpp @@ -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); diff --git a/aegisub/options.cpp b/aegisub/options.cpp index 371572f9f..a9aeb22c3 100644 --- a/aegisub/options.cpp +++ b/aegisub/options.cpp @@ -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)); diff --git a/aegisub/subtitles_provider_csri.cpp b/aegisub/subtitles_provider_csri.cpp index 042daaa9f..12e302594 100644 --- a/aegisub/subtitles_provider_csri.cpp +++ b/aegisub/subtitles_provider_csri.cpp @@ -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"