From d0c0e2a31800f69446fb56ccd6e2d6a792133eec Mon Sep 17 00:00:00 2001 From: Rodrigo Braz Monteiro Date: Tue, 9 Jan 2007 01:52:30 +0000 Subject: [PATCH] Early operation visual typesetting. Originally committed to SVN as r746. --- aegisub/Makefile.am | 1 + aegisub/ass_export_filter.cpp | 1 + aegisub/ass_export_filter.h | 1 + aegisub/ass_exporter.cpp | 2 +- aegisub/changelog.txt | 3 +- aegisub/options.cpp | 1 + aegisub/spellchecker_hunspell.cpp | 2 + aegisub/subs_edit_box.cpp | 2 +- aegisub/thesaurus_myspell.cpp | 2 + aegisub/video_display.cpp | 24 ++-- aegisub/video_display.h | 1 + aegisub/video_display_visual.cpp | 216 ++++++++++++++++++++++++++---- aegisub/video_display_visual.h | 13 +- 13 files changed, 224 insertions(+), 45 deletions(-) diff --git a/aegisub/Makefile.am b/aegisub/Makefile.am index d19cfd189..bbe84bfa5 100644 --- a/aegisub/Makefile.am +++ b/aegisub/Makefile.am @@ -69,6 +69,7 @@ aegisub_SOURCES = \ export_clean_info.cpp \ export_fixstyle.cpp \ export_framerate.cpp \ + export_visible_lines.cpp \ fft.cpp \ frame_main.cpp \ frame_main_events.cpp \ diff --git a/aegisub/ass_export_filter.cpp b/aegisub/ass_export_filter.cpp index ed6ede0a4..9e6e45cf9 100644 --- a/aegisub/ass_export_filter.cpp +++ b/aegisub/ass_export_filter.cpp @@ -43,6 +43,7 @@ /////////////// // Constructor AssExportFilter::AssExportFilter() { + hidden = false; autoExporter = false; initialized = false; FilterList *fil = AssExportFilterChain::GetUnpreparedFilterList(); diff --git a/aegisub/ass_export_filter.h b/aegisub/ass_export_filter.h index b475e2812..b5d014b3f 100644 --- a/aegisub/ass_export_filter.h +++ b/aegisub/ass_export_filter.h @@ -87,6 +87,7 @@ private: protected: bool autoExporter; + bool hidden; bool initialized; wxString description; diff --git a/aegisub/ass_exporter.cpp b/aegisub/ass_exporter.cpp index 83ffbf617..9b784986c 100644 --- a/aegisub/ass_exporter.cpp +++ b/aegisub/ass_exporter.cpp @@ -118,7 +118,7 @@ wxArrayString AssExporter::GetAllFilterNames() { FilterList::iterator begin = AssExportFilterChain::GetFilterList()->begin(); FilterList::iterator end = AssExportFilterChain::GetFilterList()->end(); for (FilterList::iterator cur=begin;cur!=end;cur++) { - names.Add((*cur)->RegisterName); + if (!(*cur)->hidden) names.Add((*cur)->RegisterName); } return names; } diff --git a/aegisub/changelog.txt b/aegisub/changelog.txt index e51700a31..6f5d81997 100644 --- a/aegisub/changelog.txt +++ b/aegisub/changelog.txt @@ -19,8 +19,7 @@ Please visit http://aegisub.net to download latest version - Plain-text export (jfs) - The style of the current line is automatically selected when opening the Style Manager (jfs) - Added long-missing Edit buttons in Style Manager (jfs) -- Various fixes to better handle paths/file names with non-ANSI characters on Windows (jfs) - o Note that this (unfortunately) doesn't affect video/audio loading, since those still depend on Avisynth, which doesn't support Unicode at all +- Various fixes to better handle paths/file names with non-ANSI characters on Windows (jfs/AMZ) - Video display fixed on Linux and maybe also Mac (Azzy) - Misc. fixes for building on Linux (Azzy) - libass support for subtitles on UNIX (Azzy) diff --git a/aegisub/options.cpp b/aegisub/options.cpp index a76176c1d..1bfc52b9c 100644 --- a/aegisub/options.cpp +++ b/aegisub/options.cpp @@ -128,6 +128,7 @@ void OptionsManager::LoadDefaults() { SetInt(_T("Video Default Zoom"), 7); SetInt(_T("Video Fast Jump Step"), 10); SetText(_T("Video Screenshot Path"),_T("?video")); + SetBool(_T("Video Visual Realtime"),false); SetModificationType(MOD_VIDEO); SetBool(_T("Show keyframes on video slider"),true); diff --git a/aegisub/spellchecker_hunspell.cpp b/aegisub/spellchecker_hunspell.cpp index 74cacf8fb..b55deda2c 100644 --- a/aegisub/spellchecker_hunspell.cpp +++ b/aegisub/spellchecker_hunspell.cpp @@ -185,6 +185,8 @@ wxArrayString HunspellSpellChecker::GetLanguageList() { // Get dir name wxString path = DecodeRelativePath(Options.AsText(_T("Dictionaries path")),AegisubApp::folderName) + _T("/"); wxArrayString list; + wxFileName folder(path); + if (!folder.DirExists()) return list; // Get file lists wxArrayString dic; diff --git a/aegisub/subs_edit_box.cpp b/aegisub/subs_edit_box.cpp index 6eee542ab..7a329b7c8 100644 --- a/aegisub/subs_edit_box.cpp +++ b/aegisub/subs_edit_box.cpp @@ -932,7 +932,7 @@ void SubsEditBox::SetOverride (wxString tagname,wxString preValue,int forcePos) bool isPos = false; bool isFlag = false; bool state = false; - AssStyle *style = AssFile::top->GetStyle(grid->GetDialogue(linen)->Style); + AssStyle *style = grid->ass->GetStyle(grid->GetDialogue(linen)->Style); AssStyle defStyle; if (style == NULL) style = &defStyle; if (tagname == _T("\\b")) { diff --git a/aegisub/thesaurus_myspell.cpp b/aegisub/thesaurus_myspell.cpp index 50a6cbad3..6a495f26f 100644 --- a/aegisub/thesaurus_myspell.cpp +++ b/aegisub/thesaurus_myspell.cpp @@ -96,6 +96,8 @@ wxArrayString MySpellThesaurus::GetLanguageList() { // Get dir name wxString path = DecodeRelativePath(Options.AsText(_T("Dictionaries path")),AegisubApp::folderName) + _T("/"); wxArrayString list; + wxFileName folder(path); + if (!folder.DirExists()) return list; // Get file lists wxArrayString idx; diff --git a/aegisub/video_display.cpp b/aegisub/video_display.cpp index a3c61ac2a..8a3aa3635 100644 --- a/aegisub/video_display.cpp +++ b/aegisub/video_display.cpp @@ -80,6 +80,7 @@ enum { // Event table BEGIN_EVENT_TABLE(VideoDisplay, wxWindow) EVT_MOUSE_EVENTS(VideoDisplay::OnMouseEvent) + EVT_KEY_DOWN(VideoDisplay::OnKey) EVT_LEAVE_WINDOW(VideoDisplay::OnMouseLeave) EVT_PAINT(VideoDisplay::OnPaint) @@ -112,16 +113,6 @@ VideoDisplay::VideoDisplay(wxWindow* parent, wxWindowID id, const wxPoint& pos, nextFrame = -1; zoomValue = 0.5; visual = new VideoDisplayVisual(this); - - // Set cursor - // Bleeeh! Hate this 'solution': -#if __WXGTK__ - static char cursor_image[] = {0}; - wxCursor cursor(cursor_image, 8, 1, -1, -1, cursor_image); -#else - wxCursor cursor(wxCURSOR_BLANK); -#endif // __WXGTK__ - SetCursor(cursor); } @@ -316,11 +307,24 @@ void VideoDisplay::OnMouseEvent(wxMouseEvent& event) { return; } + // Click? + if (event.ButtonDown(wxMOUSE_BTN_ANY)) { + SetFocus(); + } + // Send to visual visual->OnMouseEvent(event); } +///////////// +// Key event +void VideoDisplay::OnKey(wxKeyEvent &event) { + visual->OnKeyEvent(event); +} + + + ////////////////////// // Mouse left display void VideoDisplay::OnMouseLeave(wxMouseEvent& event) { diff --git a/aegisub/video_display.h b/aegisub/video_display.h index 78cea5daa..0eae6d966 100644 --- a/aegisub/video_display.h +++ b/aegisub/video_display.h @@ -95,6 +95,7 @@ private: void SaveSnapshot(); void OnPaint(wxPaintEvent& event); + void OnKey(wxKeyEvent &event); void OnMouseEvent(wxMouseEvent& event); void OnMouseLeave(wxMouseEvent& event); void OnCopyToClipboard(wxCommandEvent &event); diff --git a/aegisub/video_display_visual.cpp b/aegisub/video_display_visual.cpp index 11cbdbbd2..bc4a76e0d 100644 --- a/aegisub/video_display_visual.cpp +++ b/aegisub/video_display_visual.cpp @@ -47,10 +47,12 @@ #include "ass_file.h" #include "ass_time.h" #include "ass_dialogue.h" +#include "ass_override.h" #include "ass_style.h" #include "subs_grid.h" #include "options.h" #include "subs_edit_box.h" +#include "export_visible_lines.h" #if USE_FEXTRACKER == 1 #include "../FexTrackerSource/FexTracker.h" #include "../FexTrackerSource/FexTrackingFeature.h" @@ -63,7 +65,10 @@ VideoDisplayVisual::VideoDisplayVisual(VideoDisplay *par) { parent = par; backbuffer = NULL; + curSelection = NULL; holding = false; + mode = -1; + SetMode(0); } @@ -74,6 +79,31 @@ VideoDisplayVisual::~VideoDisplayVisual() { } +//////////// +// Set mode +void VideoDisplayVisual::SetMode(int _mode) { + // Set mode + mode = _mode; + + // Hide cursor + if (mode == 0) { + // Bleeeh! Hate this 'solution': + #if __WXGTK__ + static char cursor_image[] = {0}; + wxCursor cursor(cursor_image, 8, 1, -1, -1, cursor_image); + #else + wxCursor cursor(wxCURSOR_BLANK); + #endif // __WXGTK__ + parent->SetCursor(cursor); + } + + // Show cursor + else { + parent->SetCursor(wxNullCursor); + } +} + + //////////////// // Draw overlay void VideoDisplayVisual::DrawOverlay() { @@ -83,6 +113,8 @@ void VideoDisplayVisual::DrawOverlay() { int w = parent->w; int h = parent->h; int frame_n = parent->frame_n; + int sw,sh; + parent->GetScriptSize(sw,sh); // Create backbuffer if needed bool needCreate = false; @@ -101,27 +133,58 @@ void VideoDisplayVisual::DrawOverlay() { dc.DrawBitmap(parent->GetFrame(frame_n),0,0); // Draw the control points for FexTracker - DrawTrackingOverlay( dc ); + 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); + if (mode == 1) { + int numRows = parent->grid->GetRows(); + int startMs = VFR_Output.GetTimeAtFrame(frame_n,true); + int endMs = VFR_Output.GetTimeAtFrame(frame_n,false); + AssDialogue *diag; + dc.SetPen(wxPen(wxColour(255,0,0),1)); + + // For each line + for (int i=0;igrid->GetDialogue(i); + if (diag) { + // Draw? + bool draw = false; + int dx = -1; + int dy = -1; + + // Selected line + if (diag == curSelection) { + draw = true; + dx = cur_x * w / sw; + dy = cur_y * h / sh; + dc.SetBrush(wxBrush(wxColour(255,255,255))); + } + + // Line visible? + else if (diag->Start.GetMS() <= startMs && diag->End.GetMS() >= endMs) { + // Get position + GetLinePosition(diag,dx,dy); + dx = dx * w / sw; + dy = dy * h / sh; + + // Mouse over? + if (x >= dx-5 && x <= dx+5 && y >= dy-5 && y <= dy+5) dc.SetBrush(wxBrush(wxColour(255,255,255))); + else dc.SetBrush(wxBrush(wxColour(255,255,0))); + draw = true; + } + + // Draw + if (draw) { + dc.DrawRectangle(dx-5,dy-5,11,11); + dc.DrawLine(dx,dy-10,dx,dy+10); + dc.DrawLine(dx-10,dy,dx+10,dy); + } } } } // Current position info - if (x >= 0 && x < w && y >= 0 && y < h) { + if (mode == 0 && x >= 0 && x < w && y >= 0 && y < h) { // Draw cross dc.SetPen(wxPen(wxColour(255,255,255),1)); dc.SetLogicalFunction(wxINVERT); @@ -165,6 +228,13 @@ void VideoDisplayVisual::DrawOverlay() { //////////////////////// // Get position of line void VideoDisplayVisual::GetLinePosition(AssDialogue *diag,int &x, int &y) { + // No dialogue + if (!diag) { + x = -1; + y = -1; + return; + } + // Default values int margin[4]; for (int i=0;i<4;i++) margin[i] = diag->Margin[i]; @@ -188,8 +258,35 @@ void VideoDisplayVisual::GetLinePosition(AssDialogue *diag,int &x, int &y) { margin[1] = sw - margin[1]; margin[3] = sh - margin[3]; + // Position + int posx = -1; + int posy = -1; + // Overrides processing - // TODO + diag->ParseASSTags(); + AssDialogueBlockOverride *override; + AssOverrideTag *tag; + size_t blockn = diag->Blocks.size(); + for (size_t i=0;iBlocks.at(i)); + if (override) { + for (size_t j=0;jTags.size();j++) { + tag = override->Tags.at(j); + if ((tag->Name == _T("\\pos") || tag->Name == _("\\move")) && tag->Params.size() >= 2) { + posx = tag->Params[0]->AsInt(); + posy = tag->Params[1]->AsInt(); + } + } + } + } + diag->ClearBlocks(); + + // Got position + if (posx != -1) { + x = posx; + y = posy; + return; + } // Alignment type int hor = (align - 1) % 3; @@ -303,11 +400,16 @@ void VideoDisplayVisual::OnMouseEvent (wxMouseEvent &event) { int y = event.GetY(); int w = parent->w; int h = parent->h; + int sw,sh; + parent->GetScriptSize(sw,sh); int frame_n = parent->frame_n; VideoProvider *provider = parent->provider; SubtitlesGrid *grid = parent->grid; + bool hasOverlay = false; + bool realTime = Options.AsBool(_T("Video Visual Realtime")); -#if USE_FEXTRACKER == 1 + // FexTracker + #if USE_FEXTRACKER == 1 if( event.ButtonDown(wxMOUSE_BTN_LEFT) ) { parent->MouseDownX = x; parent->MouseDownY = y; @@ -350,55 +452,103 @@ void VideoDisplayVisual::OnMouseEvent (wxMouseEvent &event) { parent->MouseDownY = y; } } -#endif + #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(); + if (mode == 1 && event.LeftIsDown() && !holding) { + // For each line + int numRows = parent->grid->GetRows(); + int startMs = VFR_Output.GetTimeAtFrame(frame_n,true); + int endMs = VFR_Output.GetTimeAtFrame(frame_n,false); + AssDialogue *diag; + AssDialogue *gotDiag = NULL; + for (int i=0;igrid->GetDialogue(i); + if (diag) { + // Line visible? + if (diag->Start.GetMS() <= startMs && diag->End.GetMS() >= endMs) { + // Get position + int lineX,lineY; + GetLinePosition(diag,lineX,lineY); + lineX = lineX * w / sw; + lineY = lineY * h / sh; + + // Mouse over? + if (x >= lineX-5 && x <= lineX+5 && y >= lineY-5 && y <= lineY+5) { + gotDiag = diag; + orig_x = lineX; + orig_y = lineY; + break; + } + } + } + } + + // Got a line? + if (gotDiag) { + // Set dialogue + curSelection = gotDiag; + start_x = x; + start_y = y; + + // Hold it + holding = true; + hold = 1; + parent->CaptureMouse(); + hasOverlay = true; + } } // 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); + cur_x = (x - start_x + orig_x) * sw / w; + cur_y = (y - start_y + orig_y) * sh / h; + if (realTime) { + AssLimitToVisibleFilter::SetFrame(frame_n); + grid->editBox->SetOverride(_T("\\pos"),wxString::Format(_T("(%i,%i)"),cur_x,cur_y),0); + grid->editBox->CommitText(true); + grid->CommitChanges(false,true); + } } // End dragging if (holding && !event.LeftIsDown()) { + // Disable limiting + if (realTime) AssLimitToVisibleFilter::SetFrame(-1); + // Finished dragging subtitles if (hold == 1) { + grid->editBox->SetOverride(_T("\\pos"),wxString::Format(_T("(%i,%i)"),cur_x,cur_y),0); grid->editBox->CommitText(); grid->ass->FlagAsModified(); grid->CommitChanges(false,true); + curSelection = NULL; } // Set flags - holding = false; hold = 0; + holding = false; + hasOverlay = true; parent->ReleaseMouse(); + parent->SetFocus(); } // Double click - if (event.LeftDClick()) { + if (mode == 0 && 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); + parent->SetFocus(); } // Hover - bool hasOverlay = false; if (x != mouse_x || y != mouse_y) { // Set coords mouse_x = x; @@ -411,3 +561,11 @@ void VideoDisplayVisual::OnMouseEvent (wxMouseEvent &event) { DrawOverlay(); } } + + +///////////// +// Key event +void VideoDisplayVisual::OnKeyEvent(wxKeyEvent &event) { + if (event.GetKeyCode() == 'A') SetMode(0); + if (event.GetKeyCode() == 'S') SetMode(1); +} diff --git a/aegisub/video_display_visual.h b/aegisub/video_display_visual.h index 373716425..36ba176d4 100644 --- a/aegisub/video_display_visual.h +++ b/aegisub/video_display_visual.h @@ -50,17 +50,26 @@ class VideoDisplayVisual { private: int mouse_x,mouse_y; - wxBitmap *backbuffer; - wxString mouseText; + int start_x,start_y; + int cur_x,cur_y; + int orig_x,orig_y; + + int mode; bool holding; int hold; + wxBitmap *backbuffer; + wxString mouseText; + AssDialogue *curSelection; + VideoDisplay *parent; void GetLinePosition(AssDialogue *diag,int &x,int &y); void DrawTrackingOverlay(wxDC &dc); void DrawOverlay(); + void SetMode(int mode); void OnMouseEvent(wxMouseEvent &event); + void OnKeyEvent(wxKeyEvent &event); public: VideoDisplayVisual(VideoDisplay *parent);