mirror of https://github.com/odrling/Aegisub
New class to isolate visual typesetting
Originally committed to SVN as r745.
This commit is contained in:
parent
739806ea4e
commit
6ea8475941
|
@ -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 \
|
||||
|
|
|
@ -36,17 +36,17 @@
|
|||
|
||||
////////////
|
||||
// Includes
|
||||
#include "setup.h"
|
||||
#include "ass_dialogue.h"
|
||||
#include "ass_override.h"
|
||||
#include "vfr.h"
|
||||
#include "utils.h"
|
||||
#include <fstream>
|
||||
#include <wx/tokenzr.h>
|
||||
#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 //////////////////////
|
||||
|
|
|
@ -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 <wx/config.h>
|
||||
#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;i<curline->Movement->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;i<curline->Movement->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_n<StartFrame || frame_n>EndFrame ) return;
|
||||
|
||||
int localframe = frame_n - StartFrame;
|
||||
|
||||
if( curline->Tracker )
|
||||
{
|
||||
if( curline->Tracker->GetFrame() <= localframe ) return;
|
||||
|
||||
dc.SetLogicalFunction(wxCOPY);
|
||||
|
||||
for( int i=0;i<curline->Tracker->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( ++localframe<curline->Movement->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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 <wx/wxprec.h>
|
||||
#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;i<numRows;i++) {
|
||||
diag = parent->grid->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_n<StartFrame || frame_n>EndFrame ) return;
|
||||
|
||||
int localframe = frame_n - StartFrame;
|
||||
|
||||
if( curline->Tracker )
|
||||
{
|
||||
if( curline->Tracker->GetFrame() <= localframe ) return;
|
||||
|
||||
dc.SetLogicalFunction(wxCOPY);
|
||||
|
||||
for( int i=0;i<curline->Tracker->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( ++localframe<curline->Movement->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;i<curline->Movement->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;i<curline->Movement->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();
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
};
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue