From 6ea8475941157e6594bc88ac3859707d94672727 Mon Sep 17 00:00:00 2001 From: Rodrigo Braz Monteiro Date: Mon, 8 Jan 2007 21:11:06 +0000 Subject: [PATCH] New class to isolate visual typesetting Originally committed to SVN as r745. --- aegisub/Makefile.am | 3 +- aegisub/ass_dialogue.cpp | 10 +- aegisub/video_display.cpp | 266 +------------------- aegisub/video_display.h | 12 +- aegisub/video_display_visual.cpp | 413 +++++++++++++++++++++++++++++++ aegisub/video_display_visual.h | 68 +++++ aegisub/video_provider_avs.cpp | 4 + 7 files changed, 508 insertions(+), 268 deletions(-) create mode 100644 aegisub/video_display_visual.cpp create mode 100644 aegisub/video_display_visual.h diff --git a/aegisub/Makefile.am b/aegisub/Makefile.am index 373d95dfe..d19cfd189 100644 --- a/aegisub/Makefile.am +++ b/aegisub/Makefile.am @@ -64,7 +64,7 @@ aegisub_SOURCES = \ dialog_timing_processor.cpp \ dialog_tip.cpp \ dialog_translation.cpp \ - dialog_version_check.cpp + dialog_version_check.cpp \ drop.cpp \ export_clean_info.cpp \ export_fixstyle.cpp \ @@ -110,6 +110,7 @@ aegisub_SOURCES = \ vfr.cpp \ video_box.cpp \ video_display.cpp \ + video_display_visual.cpp \ video_provider.cpp \ video_provider_lavc.cpp \ video_slider.cpp \ diff --git a/aegisub/ass_dialogue.cpp b/aegisub/ass_dialogue.cpp index 6235cf3e8..81bffcd24 100644 --- a/aegisub/ass_dialogue.cpp +++ b/aegisub/ass_dialogue.cpp @@ -36,17 +36,17 @@ //////////// // Includes -#include "setup.h" -#include "ass_dialogue.h" -#include "ass_override.h" -#include "vfr.h" -#include "utils.h" #include #include #if USE_FEXTRACKER == 1 #include "../FexTrackerSource/FexTracker.h" #include "../FexTrackerSource/FexMovement.h" #endif +#include "setup.h" +#include "ass_dialogue.h" +#include "ass_override.h" +#include "vfr.h" +#include "utils.h" ////////////////////// AssDialogue ////////////////////// diff --git a/aegisub/video_display.cpp b/aegisub/video_display.cpp index dcf5a3774..a3c61ac2a 100644 --- a/aegisub/video_display.cpp +++ b/aegisub/video_display.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2005, Rodrigo Braz Monteiro +// Copyright (c) 2005-2007, Rodrigo Braz Monteiro // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -44,11 +44,13 @@ #include #include "utils.h" #include "video_display.h" +#include "video_display_visual.h" #include "video_provider.h" #include "vfr.h" #include "ass_file.h" #include "ass_time.h" #include "ass_dialogue.h" +#include "ass_style.h" #include "subs_grid.h" #include "vfw_wrap.h" #include "mkv_wrap.h" @@ -97,7 +99,6 @@ VideoDisplay::VideoDisplay(wxWindow* parent, wxWindowID id, const wxPoint& pos, audio = NULL; provider = NULL; curLine = NULL; - backbuffer = NULL; ControlSlider = NULL; PositionDisplay = NULL; loaded = false; @@ -110,6 +111,7 @@ VideoDisplay::VideoDisplay(wxWindow* parent, wxWindowID id, const wxPoint& pos, threaded = Options.AsBool(_T("Threaded Video")); nextFrame = -1; zoomValue = 0.5; + visual = new VideoDisplayVisual(this); // Set cursor // Bleeeh! Hate this 'solution': @@ -129,7 +131,7 @@ VideoDisplay::~VideoDisplay () { wxRemoveFile(tempfile); tempfile = _T(""); SetVideo(_T("")); - delete backbuffer; + delete visual; } void VideoDisplay::UpdateSize() { @@ -314,168 +316,8 @@ void VideoDisplay::OnMouseEvent(wxMouseEvent& event) { return; } - // Coords - int x = event.GetX(); - int y = event.GetY(); - -#if USE_FEXTRACKER == 1 - if( event.ButtonDown(wxMOUSE_BTN_LEFT) ) - { - MouseDownX = x; - MouseDownY = y; - bTrackerEditing = 1; - } - if( event.ButtonUp(wxMOUSE_BTN_LEFT) ) - bTrackerEditing = 0; - - // Do tracker influence if needed - if( bTrackerEditing ) - { - AssDialogue *curline = grid->GetDialogue(grid->editBox->linen); - int StartFrame, EndFrame, localframe; - if( curline - && (StartFrame = VFR_Output.GetFrameAtTime(curline->Start.GetMS(),true)) <= frame_n - && (EndFrame = VFR_Output.GetFrameAtTime(curline->End.GetMS(),false)) >= frame_n - ) - { - localframe = frame_n - StartFrame; - if( TrackerEdit!=0 && curline->Tracker && localframe < curline->Tracker->GetFrame() ) - curline->Tracker->InfluenceFeatures( localframe, float(x)/provider->GetZoom(), float(y)/provider->GetZoom(), TrackerEdit ); - if( MovementEdit!=0 && curline->Movement && localframe < curline->Movement->Frames.size() ) - {// no /provider->GetZoom() to improve precision - if( MovementEdit==1 ) - { - for( int i=0;iMovement->Frames.size();i++ ) - { - curline->Movement->Frames[i].Pos.x += float(x-MouseDownX); - curline->Movement->Frames[i].Pos.y += float(y-MouseDownY); - } - } - else if( MovementEdit==2 ) - { - curline->Movement->Frames[localframe].Pos.x += float(x-MouseDownX); - curline->Movement->Frames[localframe].Pos.y += float(y-MouseDownY); - } - else if( MovementEdit==3 ) - { - for( int i=0;i<=localframe;i++ ) - { - curline->Movement->Frames[i].Pos.x += float(x-MouseDownX); - curline->Movement->Frames[i].Pos.y += float(y-MouseDownY); - } - } - else if( MovementEdit==4 ) - { - for( int i=localframe;iMovement->Frames.size();i++ ) - { - curline->Movement->Frames[i].Pos.x += float(x-MouseDownX); - curline->Movement->Frames[i].Pos.y += float(y-MouseDownY); - } - } - } - MouseDownX = x; - MouseDownY = y; - } - } -#endif - - // Text of current coords - int sw,sh; - GetScriptSize(sw,sh); - int vx = (sw * x + w/2) / w; - int vy = (sh * y + h/2) / h; - wxString text; - if (!event.ShiftDown()) text = wxString::Format(_T("%i,%i"),vx,vy); - else text = wxString::Format(_T("%i,%i"),vx - sw,vy - sh); - - // Double click - if (event.LeftDClick()) { - grid->editBox->SetOverride(_T("\\pos"),wxString::Format(_T("(%i,%i)"),vx,vy),0); - grid->editBox->CommitText(); - grid->ass->FlagAsModified(); - grid->CommitChanges(false,true); - } - - // Drag - if (event.LeftIsDown() && false) { - grid->editBox->SetOverride(_T("\\pos"),wxString::Format(_T("(%i,%i)"),vx,vy),0); - grid->editBox->CommitText(true); - //grid->ass->FlagAsModified(); - grid->CommitChanges(false,true); - } - - // Hover - bool hasOverlay = false; - if (x != mouse_x || y != mouse_y) { - // Set coords - mouse_x = x; - mouse_y = y; - hasOverlay = true; - } - - // Has something to draw - if (hasOverlay) { - // Create backbuffer if needed - bool needCreate = false; - if (!backbuffer) needCreate = true; - else if (backbuffer->GetWidth() != w || backbuffer->GetHeight() != h) { - needCreate = true; - delete backbuffer; - } - if (needCreate) backbuffer = new wxBitmap(w,h); - - // Prepare drawing - wxMemoryDC dc; - dc.SelectObject(*backbuffer); - - // Draw frame - dc.DrawBitmap(GetFrame(frame_n),0,0); - - // Draw the control points for FexTracker - DrawTrackingOverlay( dc ); - - // Prepare grid - dc.SetPen(wxPen(wxColour(255,255,255),1)); - dc.SetLogicalFunction(wxINVERT); - - // Current position info - if (x >= 0 && x < w && y >= 0 && y < h) { - // Draw cross - dc.DrawLine(0,y,w-1,y); - dc.DrawLine(x,0,x,h-1); - - // Setup text - wxFont font(10,wxFONTFAMILY_DEFAULT,wxFONTSTYLE_NORMAL,wxFONTWEIGHT_BOLD,false,_T("Verdana")); - dc.SetFont(font); - int tw,th; - GetTextExtent(text,&tw,&th,NULL,NULL,&font); - - // Inversion - bool left = x > w/2; - bool bottom = y < h/2; - - // Text draw coords - int dx = x,dy = y; - if (left) dx -= tw + 4; - else dx += 4; - if (bottom) dy += 3; - else dy -= th + 3; - - // Draw text - dc.SetTextForeground(wxColour(64,64,64)); - dc.DrawText(text,dx+1,dy-1); - dc.DrawText(text,dx+1,dy+1); - dc.DrawText(text,dx-1,dy-1); - dc.DrawText(text,dx-1,dy+1); - dc.SetTextForeground(wxColour(255,255,255)); - dc.DrawText(text,dx,dy); - } - - // Blit to screen - wxClientDC dcScreen(this); - //dcScreen.DrawBitmap(backbuffer,0,0); - dcScreen.Blit(0,0,w,h,&dc,0,0); - } + // Send to visual + visual->OnMouseEvent(event); } @@ -702,102 +544,14 @@ void VideoDisplay::OnCopyCoords(wxCommandEvent &event) { if (wxTheClipboard->Open()) { int sw,sh; GetScriptSize(sw,sh); - int vx = (sw * mouse_x + w/2) / w; - int vy = (sh * mouse_y + h/2) / h; + int vx = (sw * visual->mouse_x + w/2) / w; + int vy = (sh * visual->mouse_y + h/2) / h; wxTheClipboard->SetData(new wxTextDataObject(wxString::Format(_T("%i,%i"),vx,vy))); wxTheClipboard->Close(); } } -////////////////// -// Draw Tracking Overlay -void VideoDisplay::DrawTrackingOverlay( wxDC &dc ) -{ -#if USE_FEXTRACKER == 1 - if( IsPlaying ) return; - - // Get line - AssDialogue *curline = grid->GetDialogue(grid->editBox->linen); - if( !curline ) return; - - int StartFrame = VFR_Output.GetFrameAtTime(curline->Start.GetMS(),true); - int EndFrame = VFR_Output.GetFrameAtTime(curline->End.GetMS(),false); - - if( frame_nEndFrame ) return; - - int localframe = frame_n - StartFrame; - - if( curline->Tracker ) - { - if( curline->Tracker->GetFrame() <= localframe ) return; - - dc.SetLogicalFunction(wxCOPY); - - for( int i=0;iTracker->GetCount();i++ ) - { - FexTrackingFeature* f = (*curline->Tracker)[i]; - if( f->StartTime > localframe ) continue; - int llf = localframe - f->StartTime; - if( f->Pos.size() <= llf ) continue; - vec2 pt = f->Pos[llf]; - pt.x *= provider->GetZoom(); - pt.y *= provider->GetZoom(); - pt.x = int(pt.x); - pt.y = int(pt.y); - - dc.SetPen(wxPen(wxColour(255*(1-f->Influence),255*f->Influence,0),1)); - - dc.DrawLine( pt.x-2, pt.y, pt.x, pt.y ); - dc.DrawLine( pt.x, pt.y-2, pt.x, pt.y ); - dc.DrawLine( pt.x+1, pt.y, pt.x+3, pt.y ); - dc.DrawLine( pt.x, pt.y+1, pt.x, pt.y+3 ); - } - } - if( curline->Movement ) - { - if( curline->Movement->Frames.size() <= localframe ) return; - - dc.SetPen(wxPen(wxColour(255,0,0),2)); - FexMovementFrame f = curline->Movement->Frames.lVal[localframe]; - f.Pos.x *= provider->GetZoom(); - f.Pos.y *= provider->GetZoom(); - f.Scale.x *= 30* provider->GetZoom(); - f.Scale.y *= 30* provider->GetZoom(); - - FexMovementFrame f3 = f; - dc.SetPen(wxPen(wxColour(0,0,255),1)); - int nBack = 8; - while( --localframe>0 && nBack-- >0 ) - { - FexMovementFrame f2 = curline->Movement->Frames.lVal[localframe]; - f2.Pos.x *= provider->GetZoom(); - f2.Pos.y *= provider->GetZoom(); - dc.DrawLine( f2.Pos.x, f2.Pos.y, f3.Pos.x, f3.Pos.y ); - f3 = f2; - } - - dc.SetPen(wxPen(wxColour(255,0,0),2)); - dc.DrawLine( f.Pos.x-f.Scale.x, f.Pos.y, f.Pos.x+f.Scale.x+1, f.Pos.y ); - dc.DrawLine( f.Pos.x, f.Pos.y-f.Scale.y, f.Pos.x, f.Pos.y+f.Scale.y+1 ); - - f3 = f; - dc.SetPen(wxPen(wxColour(0,255,0),1)); - int nFront = 8; - localframe = frame_n - StartFrame; - while( ++localframeMovement->Frames.size() && nFront-- >0 ) - { - FexMovementFrame f2 = curline->Movement->Frames.lVal[localframe]; - f2.Pos.x *= provider->GetZoom(); - f2.Pos.y *= provider->GetZoom(); - dc.DrawLine( f2.Pos.x, f2.Pos.y, f3.Pos.x, f3.Pos.y ); - f3 = f2; - } - } -#endif -} - - ////////////////// // Refresh screen void VideoDisplay::RefreshVideo() { @@ -806,7 +560,7 @@ void VideoDisplay::RefreshVideo() { dc.DrawBitmap(GetFrame(),0,0); // Draw the control points for FexTracker - DrawTrackingOverlay( dc ); + visual->DrawTrackingOverlay(dc); } diff --git a/aegisub/video_display.h b/aegisub/video_display.h index 36135584c..78cea5daa 100644 --- a/aegisub/video_display.h +++ b/aegisub/video_display.h @@ -1,4 +1,4 @@ -// Copyright (c) 2005, Rodrigo Braz Monteiro +// Copyright (c) 2005-2007, Rodrigo Braz Monteiro // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -55,18 +55,18 @@ class AudioProvider; class AudioDisplay; class AssDialogue; class VideoProvider; +class VideoDisplayVisual; + ////////////// // Main class class VideoDisplay: public wxWindow { friend class AudioProvider; + friend class VideoDisplayVisual; private: wxString tempfile; - int mouse_x,mouse_y; - wxBitmap *backbuffer; - wxSize origSize; bool threaded; int nextFrame; @@ -86,6 +86,8 @@ private: double arValue; int arType; + VideoDisplayVisual *visual; + wxBitmap GetFrame(int n); wxBitmap GetFrame() { return GetFrame(frame_n); }; @@ -100,8 +102,6 @@ private: void OnCopyCoords(wxCommandEvent &event); void OnPlayTimer(wxTimerEvent &event); - void DrawTrackingOverlay( wxDC &dc ); - public: wxArrayInt GetKeyFrames(); void SetKeyFrames(wxArrayInt frames); diff --git a/aegisub/video_display_visual.cpp b/aegisub/video_display_visual.cpp new file mode 100644 index 000000000..11cbdbbd2 --- /dev/null +++ b/aegisub/video_display_visual.cpp @@ -0,0 +1,413 @@ +// Copyright (c) 2005-2007, Rodrigo Braz Monteiro +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of the Aegisub Group nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// ----------------------------------------------------------------------------- +// +// AEGISUB +// +// Website: http://aegisub.cellosoft.com +// Contact: mailto:zeratul@cellosoft.com +// + + +#pragma once + + +////////////// +// Headers +#include +#include "video_display_visual.h" +#include "video_display.h" +#include "video_provider.h" +#include "vfr.h" +#include "ass_file.h" +#include "ass_time.h" +#include "ass_dialogue.h" +#include "ass_style.h" +#include "subs_grid.h" +#include "options.h" +#include "subs_edit_box.h" +#if USE_FEXTRACKER == 1 +#include "../FexTrackerSource/FexTracker.h" +#include "../FexTrackerSource/FexTrackingFeature.h" +#include "../FexTrackerSource/FexMovement.h" +#endif + + +/////////////// +// Constructor +VideoDisplayVisual::VideoDisplayVisual(VideoDisplay *par) { + parent = par; + backbuffer = NULL; + holding = false; +} + + +////////////// +// Destructor +VideoDisplayVisual::~VideoDisplayVisual() { + delete backbuffer; +} + + +//////////////// +// Draw overlay +void VideoDisplayVisual::DrawOverlay() { + // Variables + int x = mouse_x; + int y = mouse_y; + int w = parent->w; + int h = parent->h; + int frame_n = parent->frame_n; + + // Create backbuffer if needed + bool needCreate = false; + if (!backbuffer) needCreate = true; + else if (backbuffer->GetWidth() != w || backbuffer->GetHeight() != h) { + needCreate = true; + delete backbuffer; + } + if (needCreate) backbuffer = new wxBitmap(w,h); + + // Prepare drawing + wxMemoryDC dc; + dc.SelectObject(*backbuffer); + + // Draw frame + dc.DrawBitmap(parent->GetFrame(frame_n),0,0); + + // Draw the control points for FexTracker + DrawTrackingOverlay( dc ); + + // Draw pivot points of visible lines + int numRows = parent->grid->GetRows(); + int curMs = VFR_Output.GetTimeAtFrame(frame_n); + AssDialogue *diag; + dc.SetPen(wxPen(wxColour(255,0,0),1)); + for (int i=0;igrid->GetDialogue(i); + if (diag) { + if (diag->Start.GetMS() <= curMs && diag->End.GetMS() >= curMs) { + int lineX,lineY; + GetLinePosition(diag,lineX,lineY); + dc.DrawLine(lineX,lineY-5,lineX,lineY+5); + dc.DrawLine(lineX-5,lineY,lineX+5,lineY); + } + } + } + + // Current position info + if (x >= 0 && x < w && y >= 0 && y < h) { + // Draw cross + dc.SetPen(wxPen(wxColour(255,255,255),1)); + dc.SetLogicalFunction(wxINVERT); + dc.DrawLine(0,y,w-1,y); + dc.DrawLine(x,0,x,h-1); + + // Setup text + wxFont font(10,wxFONTFAMILY_DEFAULT,wxFONTSTYLE_NORMAL,wxFONTWEIGHT_BOLD,false,_T("Verdana")); + dc.SetFont(font); + int tw,th; + parent->GetTextExtent(mouseText,&tw,&th,NULL,NULL,&font); + + // Inversion + bool left = x > w/2; + bool bottom = y < h/2; + + // Text draw coords + int dx = x,dy = y; + if (left) dx -= tw + 4; + else dx += 4; + if (bottom) dy += 3; + else dy -= th + 3; + + // Draw text + dc.SetTextForeground(wxColour(64,64,64)); + dc.DrawText(mouseText,dx+1,dy-1); + dc.DrawText(mouseText,dx+1,dy+1); + dc.DrawText(mouseText,dx-1,dy-1); + dc.DrawText(mouseText,dx-1,dy+1); + dc.SetTextForeground(wxColour(255,255,255)); + dc.DrawText(mouseText,dx,dy); + } + + // Blit to screen + wxClientDC dcScreen(parent); + //dcScreen.DrawBitmap(backbuffer,0,0); + dcScreen.Blit(0,0,w,h,&dc,0,0); +} + + +//////////////////////// +// Get position of line +void VideoDisplayVisual::GetLinePosition(AssDialogue *diag,int &x, int &y) { + // Default values + int margin[4]; + for (int i=0;i<4;i++) margin[i] = diag->Margin[i]; + int align = 2; + + // Get style + AssStyle *style = parent->grid->ass->GetStyle(diag->Style); + if (style) { + align = style->alignment; + for (int i=0;i<4;i++) { + if (margin[i] == 0) margin[i] = style->Margin[i]; + } + } + + // Script size + int sw,sh; + parent->GetScriptSize(sw,sh); + + // Process margins + margin[3] = margin[2]; + margin[1] = sw - margin[1]; + margin[3] = sh - margin[3]; + + // Overrides processing + // TODO + + // Alignment type + int hor = (align - 1) % 3; + int vert = (align - 1) / 3; + + // Calculate positions + if (hor == 0) x = margin[0]; + else if (hor == 1) x = (margin[0] + margin[1])/2; + else if (hor == 2) x = margin[1]; + if (vert == 0) y = margin[3]; + else if (vert == 1) y = (margin[2] + margin[3])/2; + else if (vert == 2) y = margin[2]; +} + + +////////////////// +// Draw Tracking Overlay +void VideoDisplayVisual::DrawTrackingOverlay( wxDC &dc ) +{ +#if USE_FEXTRACKER == 1 + int frame_n = parent->frame_n; + VideoProvider *provider = parent->provider; + if( parent->IsPlaying ) return; + + // Get line + AssDialogue *curline = parent->grid->GetDialogue(parent->grid->editBox->linen); + if( !curline ) return; + + int StartFrame = VFR_Output.GetFrameAtTime(curline->Start.GetMS(),true); + int EndFrame = VFR_Output.GetFrameAtTime(curline->End.GetMS(),false); + + if( frame_nEndFrame ) return; + + int localframe = frame_n - StartFrame; + + if( curline->Tracker ) + { + if( curline->Tracker->GetFrame() <= localframe ) return; + + dc.SetLogicalFunction(wxCOPY); + + for( int i=0;iTracker->GetCount();i++ ) + { + FexTrackingFeature* f = (*curline->Tracker)[i]; + if( f->StartTime > localframe ) continue; + int llf = localframe - f->StartTime; + if( f->Pos.size() <= llf ) continue; + vec2 pt = f->Pos[llf]; + pt.x *= provider->GetZoom(); + pt.y *= provider->GetZoom(); + pt.x = int(pt.x); + pt.y = int(pt.y); + + dc.SetPen(wxPen(wxColour(255*(1-f->Influence),255*f->Influence,0),1)); + + dc.DrawLine( pt.x-2, pt.y, pt.x, pt.y ); + dc.DrawLine( pt.x, pt.y-2, pt.x, pt.y ); + dc.DrawLine( pt.x+1, pt.y, pt.x+3, pt.y ); + dc.DrawLine( pt.x, pt.y+1, pt.x, pt.y+3 ); + } + } + if( curline->Movement ) + { + if( curline->Movement->Frames.size() <= localframe ) return; + + dc.SetPen(wxPen(wxColour(255,0,0),2)); + FexMovementFrame f = curline->Movement->Frames.lVal[localframe]; + f.Pos.x *= provider->GetZoom(); + f.Pos.y *= provider->GetZoom(); + f.Scale.x *= 30* provider->GetZoom(); + f.Scale.y *= 30* provider->GetZoom(); + + FexMovementFrame f3 = f; + dc.SetPen(wxPen(wxColour(0,0,255),1)); + int nBack = 8; + while( --localframe>0 && nBack-- >0 ) + { + FexMovementFrame f2 = curline->Movement->Frames.lVal[localframe]; + f2.Pos.x *= provider->GetZoom(); + f2.Pos.y *= provider->GetZoom(); + dc.DrawLine( f2.Pos.x, f2.Pos.y, f3.Pos.x, f3.Pos.y ); + f3 = f2; + } + + dc.SetPen(wxPen(wxColour(255,0,0),2)); + dc.DrawLine( f.Pos.x-f.Scale.x, f.Pos.y, f.Pos.x+f.Scale.x+1, f.Pos.y ); + dc.DrawLine( f.Pos.x, f.Pos.y-f.Scale.y, f.Pos.x, f.Pos.y+f.Scale.y+1 ); + + f3 = f; + dc.SetPen(wxPen(wxColour(0,255,0),1)); + int nFront = 8; + localframe = frame_n - StartFrame; + while( ++localframeMovement->Frames.size() && nFront-- >0 ) + { + FexMovementFrame f2 = curline->Movement->Frames.lVal[localframe]; + f2.Pos.x *= provider->GetZoom(); + f2.Pos.y *= provider->GetZoom(); + dc.DrawLine( f2.Pos.x, f2.Pos.y, f3.Pos.x, f3.Pos.y ); + f3 = f2; + } + } +#endif +} + + +/////////////// +// Mouse event +void VideoDisplayVisual::OnMouseEvent (wxMouseEvent &event) { + // Coords + int x = event.GetX(); + int y = event.GetY(); + int w = parent->w; + int h = parent->h; + int frame_n = parent->frame_n; + VideoProvider *provider = parent->provider; + SubtitlesGrid *grid = parent->grid; + +#if USE_FEXTRACKER == 1 + if( event.ButtonDown(wxMOUSE_BTN_LEFT) ) { + parent->MouseDownX = x; + parent->MouseDownY = y; + parent->bTrackerEditing = 1; + } + if( event.ButtonUp(wxMOUSE_BTN_LEFT) ) parent->bTrackerEditing = 0; + + // Do tracker influence if needed + if( parent->bTrackerEditing ) { + AssDialogue *curline = parent->grid->GetDialogue(parent->grid->editBox->linen); + int StartFrame, EndFrame, localframe; + if( curline && (StartFrame = VFR_Output.GetFrameAtTime(curline->Start.GetMS(),true)) <= frame_n && (EndFrame = VFR_Output.GetFrameAtTime(curline->End.GetMS(),false)) >= frame_n ) { + localframe = frame_n - StartFrame; + if( parent->TrackerEdit!=0 && curline->Tracker && localframe < curline->Tracker->GetFrame() ) curline->Tracker->InfluenceFeatures( localframe, float(x)/provider->GetZoom(), float(y)/provider->GetZoom(), parent->TrackerEdit ); + if( parent->MovementEdit!=0 && curline->Movement && localframe < curline->Movement->Frames.size() ) {// no /provider->GetZoom() to improve precision + if( parent->MovementEdit==1 ) { + for( int i=0;iMovement->Frames.size();i++ ) { + curline->Movement->Frames[i].Pos.x += float(x-parent->MouseDownX); + curline->Movement->Frames[i].Pos.y += float(y-parent->MouseDownY); + } + } + else if( parent->MovementEdit==2 ) { + curline->Movement->Frames[localframe].Pos.x += float(x-parent->MouseDownX); + curline->Movement->Frames[localframe].Pos.y += float(y-parent->MouseDownY); + } + else if( parent->MovementEdit==3 ) { + for( int i=0;i<=localframe;i++ ) { + curline->Movement->Frames[i].Pos.x += float(x-parent->MouseDownX); + curline->Movement->Frames[i].Pos.y += float(y-parent->MouseDownY); + } + } + else if( parent->MovementEdit==4 ) { + for( int i=localframe;iMovement->Frames.size();i++ ) { + curline->Movement->Frames[i].Pos.x += float(x-parent->MouseDownX); + curline->Movement->Frames[i].Pos.y += float(y-parent->MouseDownY); + } + } + } + parent->MouseDownX = x; + parent->MouseDownY = y; + } + } +#endif + + // Text of current coords + int sw,sh; + parent->GetScriptSize(sw,sh); + int vx = (sw * x + w/2) / w; + int vy = (sh * y + h/2) / h; + if (!event.ShiftDown()) mouseText = wxString::Format(_T("%i,%i"),vx,vy); + else mouseText = wxString::Format(_T("%i,%i"),vx - sw,vy - sh); + + // Start dragging + if (event.LeftIsDown() && !holding) { + holding = true; + hold = 0; + parent->CaptureMouse(); + } + + // Drag + if (hold == 1) { + //grid->editBox->SetOverride(_T("\\pos"),wxString::Format(_T("(%i,%i)"),vx,vy),0); + //grid->editBox->CommitText(true); + //grid->CommitChanges(false,true); + } + + // End dragging + if (holding && !event.LeftIsDown()) { + // Finished dragging subtitles + if (hold == 1) { + grid->editBox->CommitText(); + grid->ass->FlagAsModified(); + grid->CommitChanges(false,true); + } + + // Set flags + holding = false; + hold = 0; + parent->ReleaseMouse(); + } + + // Double click + if (event.LeftDClick()) { + grid->editBox->SetOverride(_T("\\pos"),wxString::Format(_T("(%i,%i)"),vx,vy),0); + grid->editBox->CommitText(); + grid->ass->FlagAsModified(); + grid->CommitChanges(false,true); + } + + // Hover + bool hasOverlay = false; + if (x != mouse_x || y != mouse_y) { + // Set coords + mouse_x = x; + mouse_y = y; + hasOverlay = true; + } + + // Has something to draw + if (hasOverlay) { + DrawOverlay(); + } +} diff --git a/aegisub/video_display_visual.h b/aegisub/video_display_visual.h new file mode 100644 index 000000000..373716425 --- /dev/null +++ b/aegisub/video_display_visual.h @@ -0,0 +1,68 @@ +// Copyright (c) 2007, Rodrigo Braz Monteiro +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of the Aegisub Group nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// ----------------------------------------------------------------------------- +// +// AEGISUB +// +// Website: http://aegisub.cellosoft.com +// Contact: mailto:zeratul@cellosoft.com +// + + +#pragma once + + +////////////// +// Prototypes +class VideoDisplay; +class AssDialogue; + + +//////////////////////// +// Visual handler class +class VideoDisplayVisual { + friend class VideoDisplay; + +private: + int mouse_x,mouse_y; + wxBitmap *backbuffer; + wxString mouseText; + bool holding; + int hold; + + VideoDisplay *parent; + + void GetLinePosition(AssDialogue *diag,int &x,int &y); + void DrawTrackingOverlay(wxDC &dc); + void DrawOverlay(); + void OnMouseEvent(wxMouseEvent &event); + +public: + VideoDisplayVisual(VideoDisplay *parent); + ~VideoDisplayVisual(); +}; diff --git a/aegisub/video_provider_avs.cpp b/aegisub/video_provider_avs.cpp index 4331c299a..6662add5e 100644 --- a/aegisub/video_provider_avs.cpp +++ b/aegisub/video_provider_avs.cpp @@ -324,6 +324,10 @@ PClip AvisynthVideoProvider::ApplyDARZoom(double _zoom, double _dar, PClip video int w = vil.height * _zoom * _dar; int h = vil.height * _zoom; + if (w == vil.width && h == vil.height) { + vi = vil; + return (env->Invoke("Cache",videosource)).AsClip(); + } try { // Resize