From d9006b0eb413bd8c49900aa32e5d1d763afb81fb Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Tue, 7 Dec 2010 19:09:21 +0000 Subject: [PATCH] Make VideoContext use events for some of its communication with other objects Originally committed to SVN as r4900. --- aegisub/src/audio_display.cpp | 7 +- aegisub/src/frame_main.cpp | 4 +- aegisub/src/frame_main_events.cpp | 15 +--- aegisub/src/subs_grid.cpp | 17 ++++- aegisub/src/subs_grid.h | 8 +++ aegisub/src/video_box.cpp | 1 - aegisub/src/video_context.cpp | 55 ++------------ aegisub/src/video_context.h | 26 ++++--- aegisub/src/video_display.cpp | 22 ++++-- aegisub/src/video_display.h | 26 +++---- aegisub/src/video_slider.cpp | 116 +++++++++++------------------- aegisub/src/video_slider.h | 19 ++--- 12 files changed, 132 insertions(+), 184 deletions(-) diff --git a/aegisub/src/audio_display.cpp b/aegisub/src/audio_display.cpp index a238c1161..ebf0972be 100644 --- a/aegisub/src/audio_display.cpp +++ b/aegisub/src/audio_display.cpp @@ -58,7 +58,6 @@ #include "fft.h" #include "hotkeys.h" #include "include/aegisub/audio_player.h" -#include "include/aegisub/audio_provider.h" #include "main.h" #include "standard_paths.h" #include "subs_edit_box.h" @@ -123,6 +122,11 @@ AudioDisplay::AudioDisplay(wxWindow *parent) h -= OPT_GET("Audio/Display/Draw/Timeline")->GetBool() ? 20 : 0; SetSamplesPercent(50,false); + VideoContext *vc = VideoContext::Get(); + vc->AddKeyframesOpenListener(&AudioDisplay::Update, this); + if (OPT_GET("Audio/Display/Draw/Video Position")->GetBool()) + vc->AddSeekListener(&AudioDisplay::UpdateImage, this, false); + // Set cursor //wxCursor cursor(wxCURSOR_BLANK); //SetCursor(cursor); @@ -2221,4 +2225,3 @@ void AudioDisplay::UpdateTimeEditCtrls() { grid->editBox->EndTime->SetTime(curEndMS); grid->editBox->Duration->SetTime(curEndMS-curStartMS); } - diff --git a/aegisub/src/frame_main.cpp b/aegisub/src/frame_main.cpp index 6f410ce61..702c1ea47 100644 --- a/aegisub/src/frame_main.cpp +++ b/aegisub/src/frame_main.cpp @@ -852,7 +852,6 @@ void FrameMain::SetDisplayMode(int video, int audio) { MainSizer->RecalcSizes(); MainSizer->Layout(); Layout(); - if (showVideo) VideoContext::Get()->UpdateDisplays(true); if (didFreeze) Thaw(); } @@ -1012,7 +1011,7 @@ void FrameMain::SynchronizeProject(bool fromSubs) { wxString ar = _T("0"); wxString zoom = _T("6"); if (VideoContext::Get()->IsLoaded()) { - seekpos = wxString::Format(_T("%i"),videoBox->videoDisplay->GetFrame()); + seekpos = wxString::Format(_T("%i"),VideoContext::Get()->GetFrameN()); zoom = wxString::Format(_T("%f"),videoBox->videoDisplay->GetZoom()); int arType = VideoContext::Get()->GetAspectRatioType(); @@ -1176,7 +1175,6 @@ void FrameMain::DetachVideo(bool detach) { if (!detachedVideo) { detachedVideo = new DialogDetachedVideo(this, videoBox->videoDisplay->GetClientSize()); detachedVideo->Show(); - VideoContext::Get()->UpdateDisplays(true); } } else if (detachedVideo) { diff --git a/aegisub/src/frame_main_events.cpp b/aegisub/src/frame_main_events.cpp index 309320a86..d0769fbed 100644 --- a/aegisub/src/frame_main_events.cpp +++ b/aegisub/src/frame_main_events.cpp @@ -535,18 +535,13 @@ void FrameMain::OnOpenRecentTimecodes(wxCommandEvent &event) { /// @brief Open recent Keyframes entry /// @param event void FrameMain::OnOpenRecentKeyframes(wxCommandEvent &event) { - int number = event.GetId()-Menu_Keyframes_Recent; - VideoContext::Get()->LoadKeyframes(lagi_wxString(config::mru->GetEntry("Keyframes", number))); - videoBox->videoSlider->Refresh(); - audioBox->audioDisplay->Update(); - Refresh(); + VideoContext::Get()->LoadKeyframes(lagi_wxString(config::mru->GetEntry("Keyframes", event.GetId()-Menu_Keyframes_Recent))); } /// @brief Open recent audio menu entry /// @param event void FrameMain::OnOpenRecentAudio(wxCommandEvent &event) { - int number = event.GetId()-Menu_Audio_Recent; - LoadAudio(lagi_wxString(config::mru->GetEntry("Audio", number))); + LoadAudio(lagi_wxString(config::mru->GetEntry("Audio", event.GetId()-Menu_Audio_Recent))); } /// @brief Open new Window @@ -813,17 +808,11 @@ void FrameMain::OnOpenKeyframes (wxCommandEvent &) { // Load VideoContext::Get()->LoadKeyframes(filename); - videoBox->videoSlider->Refresh(); - audioBox->audioDisplay->Update(); - Refresh(); } /// @brief Close keyframes void FrameMain::OnCloseKeyframes (wxCommandEvent &) { VideoContext::Get()->CloseKeyframes(); - videoBox->videoSlider->Refresh(); - audioBox->audioDisplay->Update(); - Refresh(); } /// @brief Save keyframes diff --git a/aegisub/src/subs_grid.cpp b/aegisub/src/subs_grid.cpp index 6c6b8ffc5..dd9402870 100644 --- a/aegisub/src/subs_grid.cpp +++ b/aegisub/src/subs_grid.cpp @@ -62,7 +62,6 @@ #include "subs_grid.h" #include "utils.h" #include "video_context.h" -#include "video_display.h" BEGIN_EVENT_TABLE(SubtitlesGrid, BaseGrid) EVT_KEY_DOWN(SubtitlesGrid::OnKeyDown) @@ -107,6 +106,11 @@ SubtitlesGrid::SubtitlesGrid(FrameMain* parentFr, wxWindow *parent, wxWindowID i byFrame = false; editBox = NULL; parentFrame = parentFr; + + seekListener = VideoContext::Get()->AddSeekListener(&SubtitlesGrid::Refresh, this, false, (const wxRect *)NULL); + + OnHighlightVisibleChange(*OPT_GET("Subtitle/Grid/Highlight Subtitles in Frame")); + OPT_SUB("Subtitle/Grid/Highlight Subtitles in Frame", &SubtitlesGrid::OnHighlightVisibleChange, this); } /// @brief Destructor @@ -665,7 +669,7 @@ void SubtitlesGrid::OnAudioClip(wxCommandEvent &) { if (!filename.empty()) { std::ofstream outfile(filename.mb_str(csConvLocal),std::ios::binary); - + size_t bufsize=(end-start)*provider->GetChannels()*provider->GetBytesPerSample(); int intval; short shortval; @@ -1273,3 +1277,12 @@ void SubtitlesGrid::SetSelectionFromAbsolute(std::vector &selection) { SetSelectedSet(newsel); } + +void SubtitlesGrid::OnHighlightVisibleChange(agi::OptionValue const& opt) { + if (opt.GetBool()) { + seekListener.Unblock(); + } + else { + seekListener.Block(); + } +} diff --git a/aegisub/src/subs_grid.h b/aegisub/src/subs_grid.h index d34c375dc..bed7fd4a9 100644 --- a/aegisub/src/subs_grid.h +++ b/aegisub/src/subs_grid.h @@ -46,6 +46,10 @@ #include "base_grid.h" +#include + +namespace agi { class OptionValue; } + class AssFile; class AssEntry; class AssDialogue; @@ -61,6 +65,8 @@ typedef std::list::iterator entryIter; /// DOCME class SubtitlesGrid: public BaseGrid { private: + agi::signal::Connection seekListener; + void OnPopupMenu(bool alternate=false); void OnKeyDown(wxKeyEvent &event); @@ -89,6 +95,8 @@ private: void OnAudioClip(wxCommandEvent &event); void OnShowColMenu(wxCommandEvent &event); + void OnHighlightVisibleChange(agi::OptionValue const& opt); + public: /// Currently open file AssFile *ass; diff --git a/aegisub/src/video_box.cpp b/aegisub/src/video_box.cpp index ee1f2b072..bc0cbef50 100644 --- a/aegisub/src/video_box.cpp +++ b/aegisub/src/video_box.cpp @@ -113,7 +113,6 @@ VideoBox::VideoBox(wxWindow *parent, bool isDetached, wxComboBox *zoomBox) // Display videoDisplay = new VideoDisplay(this,videoSlider,VideoPosition,VideoSubsPos,zoomBox,videoPage,-1,wxDefaultPosition,wxDefaultSize,wxSUNKEN_BORDER); - VideoContext::Get()->AddDisplay(videoDisplay); // Set display videoSlider->Display = videoDisplay; diff --git a/aegisub/src/video_context.cpp b/aegisub/src/video_context.cpp index 5e2a6e4aa..72e487653 100644 --- a/aegisub/src/video_context.cpp +++ b/aegisub/src/video_context.cpp @@ -207,7 +207,8 @@ void VideoContext::SetVideo(const wxString &filename) { } provider->LoadSubtitles(grid->ass); - UpdateDisplays(true); + VideoOpen(); + KeyframesOpen(keyFrames); } catch (agi::UserCancelException const&) { } catch (agi::FileNotAccessibleError const& err) { @@ -227,47 +228,11 @@ void VideoContext::Reload() { } } -void VideoContext::AddDisplay(VideoDisplay *display) { - if (std::find(displayList.begin(), displayList.end(), display) == displayList.end()) - displayList.push_back(display); -} - -void VideoContext::RemoveDisplay(VideoDisplay *display) { - displayList.remove(display); -} - -void VideoContext::UpdateDisplays(bool full, bool seek) { - if (!IsLoaded()) return; - - for (std::list::iterator cur=displayList.begin();cur!=displayList.end();cur++) { - VideoDisplay *display = *cur; - - if (!seek) { - display->Refresh(); - } - if (full) { - display->UpdateSize(); - display->SetFrameRange(0,GetLength()-1); - } - if (seek || full) { - display->SetFrame(GetFrameN()); - } - } - - // Update audio display - if (audio && audio->loaded && audio->IsShownOnScreen()) { - static const agi::OptionValue* opt = OPT_GET("Audio/Display/Draw/Video Position"); - if (opt->GetBool()) { - audio->UpdateImage(false); - } - } -} - void VideoContext::Refresh() { if (!IsLoaded()) return; provider->LoadSubtitles(grid->ass); - UpdateDisplays(false); + SubtitlesChange(); } void VideoContext::JumpToFrame(int n) { @@ -278,10 +243,7 @@ void VideoContext::JumpToFrame(int n) { frame_n = n; - UpdateDisplays(false, true); - - static const agi::OptionValue* highlight = OPT_GET("Subtitle/Grid/Highlight Subtitles in Frame"); - if (!isPlaying && highlight->GetBool()) grid->Refresh(false); + Seek(n); } void VideoContext::JumpToTime(int ms, agi::vfr::Time end) { @@ -481,12 +443,9 @@ double VideoContext::GetARFromType(int type) const { void VideoContext::SetAspectRatio(int type, double value) { if (type != 4) value = GetARFromType(type); - if (value < 0.5) value = 0.5; - if (value > 5.0) value = 5.0; arType = type; - arValue = value; - UpdateDisplays(true); + arValue = MID(.5, value, 5.); } void VideoContext::LoadKeyframes(wxString filename) { @@ -494,7 +453,7 @@ void VideoContext::LoadKeyframes(wxString filename) { try { keyFrames = KeyFrameFile::Load(filename); keyFramesFilename = filename; - Refresh(); + KeyframesOpen(keyFrames); } catch (const wchar_t *error) { wxMessageBox(error, _T("Error opening keyframes file"), wxOK | wxICON_ERROR, NULL); @@ -520,7 +479,7 @@ void VideoContext::CloseKeyframes() { else { keyFrames.clear(); } - Refresh(); + KeyframesOpen(keyFrames); } void VideoContext::LoadTimecodes(wxString filename) { diff --git a/aegisub/src/video_context.h b/aegisub/src/video_context.h index b732644e9..bd7bf3879 100644 --- a/aegisub/src/video_context.h +++ b/aegisub/src/video_context.h @@ -49,6 +49,7 @@ #error "Aegisub requires wxWidgets to be compiled with OpenGL support." #endif +#include #include class AegiVideoFrame; @@ -76,6 +77,17 @@ class VideoContext : public wxEvtHandler { friend class AudioProvider; friend class KeyFrameFile; + /// Current frame number changed + agi::signal::Signal Seek; + /// A new video was opened + agi::signal::Signal<> VideoOpen; + /// Subtitles file changed + /// @todo Move this to AssFile + agi::signal::Signal<> SubtitlesChange; + /// New keyframes opened + agi::signal::Signal const&> KeyframesOpen; + +private: /// DOCME std::list displayList; @@ -165,10 +177,6 @@ public: VideoContext(); ~VideoContext(); - void AddDisplay(VideoDisplay *display); - void RemoveDisplay(VideoDisplay *display); - - /// @brief Get the video provider used for the currently open video VideoProvider *GetProvider() const { return videoProvider.get(); } std::tr1::shared_ptr GetFrame(int n, bool raw = false); @@ -234,11 +242,6 @@ public: /// @brief Refresh the subtitle provider void Refresh(); - /// @brief Update the video display - /// @param full Recalculate size and slider lengths - /// @param seek Update is just a seek and file has not changed - void UpdateDisplays(bool full, bool seek = false); - /// @brief Get the height and width of the current script /// @param[out] w Width /// @param[out] h Height @@ -257,6 +260,11 @@ public: /// Stop playing void Stop(); + DEFINE_SIGNAL_ADDERS(Seek, AddSeekListener) + DEFINE_SIGNAL_ADDERS(VideoOpen, AddVideoOpenListener) + DEFINE_SIGNAL_ADDERS(KeyframesOpen, AddKeyframesOpenListener) + DEFINE_SIGNAL_ADDERS(SubtitlesChange, AddSubtitlesChangeListener) + const std::vector& GetKeyFrames() const { return keyFrames; }; wxString GetKeyFramesName() const { return keyFramesFilename; } void LoadKeyframes(wxString filename); diff --git a/aegisub/src/video_display.cpp b/aegisub/src/video_display.cpp index 6db9358e6..da29ed34d 100644 --- a/aegisub/src/video_display.cpp +++ b/aegisub/src/video_display.cpp @@ -97,6 +97,7 @@ BEGIN_EVENT_TABLE(VideoDisplay, wxGLCanvas) EVT_PAINT(VideoDisplay::OnPaint) EVT_SIZE(VideoDisplay::OnSizeEvent) EVT_ERASE_BACKGROUND(VideoDisplay::OnEraseBackground) + EVT_SHOW(VideoDisplay::OnShow) EVT_MENU(VIDEO_MENU_COPY_COORDS,VideoDisplay::OnCopyCoords) EVT_MENU(VIDEO_MENU_COPY_TO_CLIPBOARD,VideoDisplay::OnCopyToClipboard) @@ -110,7 +111,7 @@ int attribList[] = { WX_GL_RGBA , WX_GL_DOUBLEBUFFER, WX_GL_STENCIL_SIZE, 8, 0 } /// @class VideoOutRenderException /// @extends VideoOutException -/// @brief An OpenGL error occured while uploading or displaying a frame +/// @brief An OpenGL error occurred while uploading or displaying a frame class OpenGlException : public agi::Exception { public: OpenGlException(const wxChar *func, int err) @@ -155,13 +156,18 @@ VideoDisplay::VideoDisplay( { if (zoomBox) zoomBox->SetValue(wxString::Format("%g%%", zoomValue * 100.)); box->Bind(wxEVT_COMMAND_TOOL_CLICKED, &VideoDisplay::OnMode, this, Video_Mode_Standard, Video_Mode_Vector_Clip); - VideoContext::Get()->Bind(EVT_FRAME_READY, &VideoDisplay::UploadFrameData, this); + + VideoContext *vc = VideoContext::Get(); + vc->Bind(EVT_FRAME_READY, &VideoDisplay::UploadFrameData, this); + slots.push_back(vc->AddSeekListener(&VideoDisplay::SetFrame, this)); + slots.push_back(vc->AddVideoOpenListener(&VideoDisplay::OnVideoOpen, this)); + slots.push_back(vc->AddSubtitlesChangeListener(&VideoDisplay::Refresh, this)); + SetCursor(wxNullCursor); } VideoDisplay::~VideoDisplay () { VideoContext::Get()->Unbind(EVT_FRAME_READY, &VideoDisplay::UploadFrameData, this); - VideoContext::Get()->RemoveDisplay(this); } bool VideoDisplay::InitContext() { @@ -205,7 +211,6 @@ void VideoDisplay::UpdateRelativeTimes(int time) { void VideoDisplay::SetFrame(int frameNumber) { VideoContext *context = VideoContext::Get(); - ControlSlider->SetValue(frameNumber); currentFrame = frameNumber; @@ -270,8 +275,9 @@ void VideoDisplay::Refresh() { UpdateRelativeTimes(VideoContext::Get()->TimeAtFrame(currentFrame, agi::vfr::EXACT)); } -void VideoDisplay::SetFrameRange(int from, int to) { - ControlSlider->SetRange(from, to); +void VideoDisplay::OnVideoOpen() { + UpdateSize(); + Refresh(); } void VideoDisplay::Render() try { @@ -548,6 +554,10 @@ double VideoDisplay::GetZoom() const { return zoomValue; } +void VideoDisplay::OnShow(wxShowEvent&) { + OnVideoOpen(); +} + template void VideoDisplay::SetTool() { tool.reset(); diff --git a/aegisub/src/video_display.h b/aegisub/src/video_display.h index 8bae13aa4..0549dcf2a 100644 --- a/aegisub/src/video_display.h +++ b/aegisub/src/video_display.h @@ -42,6 +42,8 @@ #include #endif +#include + // Prototypes class FrameReadyEvent; class VideoSlider; @@ -64,6 +66,9 @@ struct VideoState { /// @class VideoDisplay /// @brief DOCME class VideoDisplay : public wxGLCanvas { + /// Signals the display is connected to + std::list slots; + const agi::OptionValue* alwaysShowTools; /// The unscaled size of the displayed video wxSize origSize; @@ -159,6 +164,15 @@ class VideoDisplay : public wxGLCanvas { /// @param time Currently displayed frame's time void UpdateRelativeTimes(int time); + /// @brief Set this video display to the given frame + /// @frameNumber The desired frame number + void SetFrame(int frameNumber); + /// @brief Signal that the file has changed + void Refresh(); + void OnVideoOpen(); + + void OnShow(wxShowEvent &event); + void OnMode(const wxCommandEvent &event); void SetMode(int mode); @@ -206,18 +220,6 @@ public: /// @brief Reset the size of the display to the video size void Reset(); - /// @brief Set this video display to the given frame - /// @frameNumber The desired frame number - void SetFrame(int frameNumber); - /// @brief Get the number of the currently displayed framed - int GetFrame() const { return currentFrame; } - /// @brief Set the range of valid frame numbers for the slider - /// @from Minimum frame number - /// @to Maximum frame number; must be >= from or strange things may happen - void SetFrameRange(int from, int to); - /// @brief Signal that the file has changed - void Refresh(); - /// @brief Render the currently visible frame void Render(); diff --git a/aegisub/src/video_slider.cpp b/aegisub/src/video_slider.cpp index 53ff1b836..a1bc94004 100644 --- a/aegisub/src/video_slider.cpp +++ b/aegisub/src/video_slider.cpp @@ -34,9 +34,6 @@ /// @ingroup custom_control /// - -//////////// -// Includes #include "config.h" #ifndef AGI_PRE @@ -66,17 +63,22 @@ VideoSlider::VideoSlider (wxWindow* parent, wxWindowID id) : wxWindow (parent,id,wxDefaultPosition,wxDefaultSize,wxWANTS_CHARS | wxFULL_REPAINT_ON_RESIZE) { val = 0; - min = 0; max = 1; Display = NULL; SetClientSize(20,25); SetMinSize(wxSize(20, 25)); locked = false; - SetRange(0,1); OPT_SUB("Video/Slider/Show Keyframes", &wxWindow::Refresh, this, false, (wxRect*)NULL); + VideoContext *vc = VideoContext::Get(); + assert(vc); + vc->AddSeekListener(&VideoSlider::SetValue, this); + vc->AddVideoOpenListener(&VideoSlider::VideoOpened, this); + vc->AddKeyframesOpenListener(&VideoSlider::KeyframesChanged, this); } VideoSlider::~VideoSlider() { + VideoContext *vc = VideoContext::Get(); + assert(vc); } /// @brief Set value @@ -84,29 +86,22 @@ VideoSlider::~VideoSlider() { /// @return /// void VideoSlider::SetValue(int value) { - if (locked) return; - val = value; - if (val < min) val = min; - if (val > max) val = max; + if (val == value) return; + val = MID(0, value, max); Refresh(false); } - - -/// @brief Set range -/// @param from -/// @param to -/// -void VideoSlider::SetRange(int from,int to) { - if (from > to) from = to; - locked = false; - min = from; - max = to; - if (val < from) val = from; - if (val > to) val = to; +void VideoSlider::VideoOpened() { + VideoContext *vc = VideoContext::Get(); + max = vc->GetLength() - 1; + keyframes = vc->GetKeyFrames(); + Refresh(false); } - +void VideoSlider::KeyframesChanged(std::vector const& newKeyframes) { + keyframes = newKeyframes; + Refresh(false); +} /// @brief Get value at X /// @param x @@ -121,7 +116,7 @@ int VideoSlider::GetValueAtX(int x) { if (w <= 10) return 0; // Calculate - return (int64_t)(x-5)*(int64_t)(max-min)/(int64_t)(w-10)+min; + return (int64_t)(x-5)*(int64_t)max/(int64_t)(w-10); } @@ -136,10 +131,10 @@ int VideoSlider::GetXAtValue(int value) { GetClientSize(&w,&h); // Special case - if (max-min <= 0) return 0; + if (max <= 0) return 0; // Calculate - return (int64_t)(value-min)*(int64_t)(w-10)/(int64_t)(max-min)+5; + return (int64_t)value*(int64_t)(w-10)/(int64_t)max+5; } @@ -151,7 +146,7 @@ void VideoSlider::NextFrame() { if (VideoContext::Get()->IsPlaying()) return; //don't request out of range frames - if (GetValue() < max) VideoContext::Get()->PlayNextFrame(); + if (val < max) VideoContext::Get()->PlayNextFrame(); Refresh(false); Update(); } @@ -165,14 +160,11 @@ void VideoSlider::PrevFrame() { if (VideoContext::Get()->IsPlaying()) return; //don't request out of range frames - if (GetValue() > min) VideoContext::Get()->PlayPrevFrame(); + if (val > 0) VideoContext::Get()->PlayPrevFrame(); Refresh(false); Update(); } - -/////////////// -// Event table BEGIN_EVENT_TABLE(VideoSlider, wxWindow) EVT_MOUSE_EVENTS(VideoSlider::OnMouse) EVT_KEY_DOWN(VideoSlider::OnKeyDown) @@ -182,22 +174,6 @@ BEGIN_EVENT_TABLE(VideoSlider, wxWindow) EVT_ERASE_BACKGROUND(VideoSlider::OnEraseBackground) END_EVENT_TABLE() - - -/// @brief Change position -/// @return -/// -void VideoSlider::UpdateVideo() { - if (Display) { - if (VideoContext::Get()->IsPlaying()) return; - locked = true; - VideoContext::Get()->JumpToFrame(GetValue()); - locked = false; - } -} - - - /// @brief Mouse events /// @param event /// @return @@ -214,7 +190,7 @@ void VideoSlider::OnMouse(wxMouseEvent &event) { bool canDrag = wxWindow::FindFocus() == this; if (!canDrag) { int tolerance = 4; - int curX = GetXAtValue(GetValue()); + int curX = GetXAtValue(val); if (x-curX < -tolerance || x-curX > tolerance) canDrag = true; } @@ -237,14 +213,14 @@ void VideoSlider::OnMouse(wxMouseEvent &event) { } // Jump to frame - if (closest == GetValue()) return; + if (closest == val) return; SetValue(closest); } // Normal click else { int go = GetValueAtX(x); - if (go == GetValue()) return; + if (go == val) return; SetValue(go); } Refresh(false); @@ -252,10 +228,10 @@ void VideoSlider::OnMouse(wxMouseEvent &event) { // Playing? if (VideoContext::Get()->IsPlaying()) { VideoContext::Get()->Stop(); - UpdateVideo(); + VideoContext::Get()->JumpToFrame(val); VideoContext::Get()->Play(); } - else UpdateVideo(); + else VideoContext::Get()->JumpToFrame(val); } // Get focus @@ -307,8 +283,8 @@ void VideoSlider::OnKeyDown(wxKeyEvent &event) { // Fast move if (!ctrl && !shift && alt) { if (VideoContext::Get()->IsPlaying()) return; - int target = MID(min,GetValue() + direction * OPT_GET("Video/Slider/Fast Jump Step")->GetInt(),max); - if (target != GetValue()) VideoContext::Get()->JumpToFrame(target); + int target = MID(0,val + direction * OPT_GET("Video/Slider/Fast Jump Step")->GetInt(),max); + if (target != val) VideoContext::Get()->JumpToFrame(target); return; } @@ -371,24 +347,20 @@ void VideoSlider::OnKeyDown(wxKeyEvent &event) { if (direction != 0) { // Prepare int prevKey = 0; - int nextKey = VideoContext::Get()->GetLength()-1; - std::vector KeyFrames = VideoContext::Get()->GetKeyFrames(); - int keys = KeyFrames.size(); - int cur = VideoContext::Get()->GetFrameN(); - int i; - int temp; + int nextKey = max; + int keys = keyframes.size(); // Find previous keyframe // This algorithm does unnecessary loops, but it ensures it works even if keyframes are out of order. - for (i=0;i prevKey) prevKey = temp; + for (int i=0;i prevKey) prevKey = temp; } // Find next keyframe - for (i=0;i cur && temp < nextKey) nextKey = KeyFrames[i]; + for (int i=0;i val && temp < nextKey) nextKey = temp; } if (direction == -1) VideoContext::Get()->JumpToFrame(prevKey); @@ -477,16 +449,14 @@ void VideoSlider::DrawImage(wxDC &destdc) { int curX; if (Display && OPT_GET("Video/Slider/Show Keyframes")->GetBool()) { dc.SetPen(wxPen(shad)); - std::vector KeyFrames = VideoContext::Get()->GetKeyFrames(); - int keys = KeyFrames.size(); - for (int i=0;i keyframes; /// DOCME - int min; + int val; /// DOCME int max; @@ -61,22 +60,20 @@ class VideoSlider: public wxWindow { int GetValueAtX(int x); int GetXAtValue(int value); - void UpdateVideo(); void DrawImage(wxDC &dc); void UpdateImage(); + void SetValue(int value); + + void VideoOpened(); + void KeyframesChanged(std::vector const& newKeyframes); void OnMouse(wxMouseEvent &event); void OnKeyDown(wxKeyEvent &event); void OnPaint(wxPaintEvent &event); void OnFocus(wxFocusEvent &event); - - /// @brief DOCME - /// @param event - /// void OnEraseBackground(wxEraseEvent &event) {} public: - /// DOCME VideoDisplay *Display; @@ -89,9 +86,5 @@ public: void NextFrame(); void PrevFrame(); - void SetRange(int start,int end); - int GetValue() const { return val; }; - void SetValue(int value); - DECLARE_EVENT_TABLE() };