1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        VideoFrameDlg.cpp
3 // Purpose:     The video frame dialog
4 // Author:      Alex Thuering
5 // Created:     23.12.2011
6 // RCS-ID:      $Id: VideoFrameDlg.cpp,v 1.7 2013/06/30 13:24:47 ntalex Exp $
7 // Copyright:   (c) Alex Thuering
8 // Licence:     GPL
9 /////////////////////////////////////////////////////////////////////////////
10 
11 #include "VideoFrameDlg.h"
12 
13 //(*InternalHeaders(VideoFrameDlg)
14 #include <wx/artprov.h>
15 #include <wx/bitmap.h>
16 #include <wx/intl.h>
17 #include <wx/button.h>
18 #include <wx/image.h>
19 #include <wx/string.h>
20 //*)
21 #include "Utils.h"
22 #include <wx/wx.h>
23 #include <wx/regex.h>
24 
25 //(*IdInit(VideoFrameDlg)
26 const long VideoFrameDlg::ID_MEDIA_CTRL = wxNewId();
27 const long VideoFrameDlg::ID_SLIDER = wxNewId();
28 const long VideoFrameDlg::ID_TIME_CTRL = wxNewId();
29 const long VideoFrameDlg::ID_TIME_SPINB = wxNewId();
30 const long VideoFrameDlg::ID_FRAME_SPINBT = wxNewId();
31 const long VideoFrameDlg::ID_RESET_TIME_BT = wxNewId();
32 const long VideoFrameDlg::ID_DURATION_CTRL = wxNewId();
33 //*)
34 
BEGIN_EVENT_TABLE(VideoFrameDlg,wxDialog)35 BEGIN_EVENT_TABLE(VideoFrameDlg,wxDialog)
36 	//(*EventTable(VideoFrameDlg)
37 	//*)
38 	EVT_COMMAND_SCROLL(ID_SLIDER, VideoFrameDlg::OnSliderScroll)
39 END_EVENT_TABLE()
40 
41 VideoFrameDlg::VideoFrameDlg(wxWindow* parent, wxString fileName, bool custom, long defaultPos, long pos, int duration) {
42 	m_defaultPos = defaultPos;
43 
44 	//(*Initialize(VideoFrameDlg)
45 	wxStaticText* staticText2;
46 	wxBoxSizer* boxSizer1;
47 	wxStaticText* staticText3;
48 	wxStdDialogButtonSizer* stdDialogButtonSizer;
49 	wxStaticText* staticText1;
50 	wxBoxSizer* mainSizer;
51 
52 	Create(parent, wxID_ANY, _("Video frame"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER, _T("wxID_ANY"));
53 	mainSizer = new wxBoxSizer(wxVERTICAL);
54 	m_mediaCtrl = new MediaCtrlFF(this, ID_MEDIA_CTRL, wxT(""), wxDefaultPosition,wxDefaultSize, 0, wxDefaultValidator, _T("ID_MEDIA_CTRL"));
55 	m_mediaCtrl->SetMinSize(wxSize(300, 200));
56 	m_mediaCtrl->SetWindowStyle(wxBORDER_NONE);
57 	mainSizer->Add(m_mediaCtrl, 1, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 4);
58 	m_slider = new wxSlider(this, ID_SLIDER, 0, 0, 100, wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_SLIDER"));
59 	mainSizer->Add(m_slider, 0, wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 2);
60 	boxSizer1 = new wxBoxSizer(wxHORIZONTAL);
61 	staticText1 = new wxStaticText(this, wxID_ANY, _("Time:"), wxDefaultPosition, wxDefaultSize, 0, _T("wxID_ANY"));
62 	boxSizer1->Add(staticText1, 0, wxLEFT|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 4);
63 	m_timeCtrl = new wxTextCtrl(this, ID_TIME_CTRL, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_TIME_CTRL"));
64 	boxSizer1->Add(m_timeCtrl, 0, wxLEFT|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
65 	m_timeSpinBt = new wxSpinButton(this, ID_TIME_SPINB, wxDefaultPosition, wxDefaultSize, wxSP_VERTICAL|wxSP_ARROW_KEYS, _T("ID_TIME_SPINB"));
66 	m_timeSpinBt->SetRange(0, 100);
67 	m_timeSpinBt->SetMinSize(wxSize(16,12));
68 	boxSizer1->Add(m_timeSpinBt, 0, wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
69 	m_frameSpinBt = new wxSpinButton(this, ID_FRAME_SPINBT, wxDefaultPosition, wxDefaultSize, wxSP_VERTICAL|wxSP_ARROW_KEYS|wxSP_WRAP, _T("ID_FRAME_SPINBT"));
70 	m_frameSpinBt->SetRange(-9999, 9999);
71 	m_frameSpinBt->SetMinSize(wxSize(16,12));
72 	boxSizer1->Add(m_frameSpinBt, 0, wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
73 	m_resetTimeBt = new wxBitmapButton(this, ID_RESET_TIME_BT, wxArtProvider::GetBitmap(wxART_MAKE_ART_ID_FROM_STR(_T("wxART_UNDO")),wxART_MENU), wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, _T("ID_RESET_TIME_BT"));
74 	m_resetTimeBt->SetDefault();
75 	m_resetTimeBt->SetToolTip(_("Reset"));
76 	boxSizer1->Add(m_resetTimeBt, 0, wxLEFT|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 2);
77 	staticText2 = new wxStaticText(this, wxID_ANY, _("Duration:"), wxDefaultPosition, wxDefaultSize, 0, _T("wxID_ANY"));
78 	boxSizer1->Add(staticText2, 0, wxLEFT|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 8);
79 	m_durationCtrl = new wxSpinCtrl(this, ID_DURATION_CTRL, _T("0"), wxDefaultPosition, wxSize(60,-1), 0, 0, 999, 0, _T("ID_DURATION_CTRL"));
80 	m_durationCtrl->SetValue(_T("0"));
81 	boxSizer1->Add(m_durationCtrl, 0, wxLEFT|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 4);
82 	staticText3 = new wxStaticText(this, wxID_ANY, _("sec"), wxDefaultPosition, wxDefaultSize, 0, _T("wxID_ANY"));
83 	boxSizer1->Add(staticText3, 0, wxLEFT|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 2);
84 	boxSizer1->Add(-1,-1,1, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
85 	mainSizer->Add(boxSizer1, 0, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
86 	stdDialogButtonSizer = new wxStdDialogButtonSizer();
87 	stdDialogButtonSizer->AddButton(new wxButton(this, wxID_OK, wxEmptyString));
88 	stdDialogButtonSizer->AddButton(new wxButton(this, wxID_CANCEL, wxEmptyString));
89 	stdDialogButtonSizer->Realize();
90 	mainSizer->Add(stdDialogButtonSizer, 0, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
91 	SetSizer(mainSizer);
92 	mainSizer->Fit(this);
93 	mainSizer->SetSizeHints(this);
94 	Center();
95 
96 	Connect(ID_TIME_CTRL,wxEVT_COMMAND_TEXT_UPDATED,(wxObjectEventFunction)&VideoFrameDlg::OnChangeTime);
97 	Connect(ID_TIME_SPINB,wxEVT_SCROLL_THUMBTRACK,(wxObjectEventFunction)&VideoFrameDlg::OnTimeSpin);
98 	Connect(ID_FRAME_SPINBT,wxEVT_SCROLL_LINEUP,(wxObjectEventFunction)&VideoFrameDlg::OnFrameSpin);
99 	Connect(ID_FRAME_SPINBT,wxEVT_SCROLL_LINEDOWN,(wxObjectEventFunction)&VideoFrameDlg::OnFrameSpinDown);
100 	Connect(ID_RESET_TIME_BT,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&VideoFrameDlg::OnResetBt);
101 	//*)
102 	stdDialogButtonSizer->GetAffirmativeButton()->SetDefault();
103 
104 	int x = 0;
105 	m_timeCtrl->GetTextExtent(wxT("00:00:00.000"), &x, NULL);
106 	m_timeCtrl->SetMinSize(wxSize(x + 10, -1));
107 
108 	m_mediaCtrl->Load(fileName);
109 	m_slider->SetMax(m_mediaCtrl->Length()/1000);
110 	m_timeSpinBt->SetMax(m_mediaCtrl->Length()/1000);
111 
112 	SeekVideo(pos);
113 	m_durationCtrl->SetValue(duration);
114 }
115 
~VideoFrameDlg()116 VideoFrameDlg::~VideoFrameDlg() {
117 	//(*Destroy(VideoFrameDlg)
118 	//*)
119 }
120 
SeekVideo(long pos,bool updateTimeCtrl)121 void VideoFrameDlg::SeekVideo(long pos, bool updateTimeCtrl) {
122 	m_slider->SetValue(lround(pos / 1000));
123 	m_timeSpinBt->SetValue(lround(pos / 1000));
124 	m_mediaCtrl->Seek((wxFileOffset) pos);
125 	m_resetTimeBt->Enable(pos != m_defaultPos);
126 	if (updateTimeCtrl)
127 		m_timeCtrl->ChangeValue(Time2String(pos, true));
128 	m_pos = pos;
129 }
130 
OnSliderScroll(wxScrollEvent & event)131 void VideoFrameDlg::OnSliderScroll(wxScrollEvent& event) {
132 	SeekVideo(((long)m_slider->GetValue())*1000);
133 }
134 
OnTimeSpin(wxSpinEvent & event)135 void VideoFrameDlg::OnTimeSpin(wxSpinEvent& event) {
136 	SeekVideo(((long)m_timeSpinBt->GetValue())*1000);
137 }
138 
OnChangeTime(wxCommandEvent & event)139 void VideoFrameDlg::OnChangeTime(wxCommandEvent& event) {
140 	if (s_timeRE.Matches(m_timeCtrl->GetValue()))
141 		SeekVideo(String2Time(m_timeCtrl->GetValue()), false);
142 }
143 
OnResetBt(wxCommandEvent & event)144 void VideoFrameDlg::OnResetBt(wxCommandEvent& event) {
145 	SeekVideo(m_defaultPos);
146 }
147 
OnFrameSpin(wxSpinEvent & event)148 void VideoFrameDlg::OnFrameSpin(wxSpinEvent& event) {
149 	SeekVideo(m_pos + 1000 / m_mediaCtrl->GetFps());
150 }
151 
OnFrameSpinDown(wxSpinEvent & event)152 void VideoFrameDlg::OnFrameSpinDown(wxSpinEvent& event) {
153 	long pos = m_pos - 1000 / m_mediaCtrl->GetFps();
154 	SeekVideo(pos >= 0 ? pos : 0);
155 }
156