From 263df94e69f7e39fb6d47b5bff2570f8406f9d34 Mon Sep 17 00:00:00 2001 From: Rodrigo Braz Monteiro Date: Sat, 7 Apr 2007 02:39:18 +0000 Subject: [PATCH] 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. --- aegisub/audio_display.cpp | 212 ++++++++++++++++------------ aegisub/audio_display.h | 4 +- aegisub/dialog_options.cpp | 18 ++- aegisub/options.cpp | 3 + aegisub/subtitles_provider_csri.cpp | 2 +- 5 files changed, 138 insertions(+), 101 deletions(-) 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"