#include "control_film_viewer.h"
#include "film_viewer.h"
#include "wx_util.h"
+#include "playhead_to_timecode_dialog.h"
+#include "playhead_to_frame_dialog.h"
+#include "lib/job_manager.h"
#include <wx/wx.h>
#include <wx/tglbtn.h>
using std::string;
using boost::optional;
+using boost::shared_ptr;
+using boost::weak_ptr;
+/** @param outline_content true if viewer should present an "outline content" checkbox.
+ * @param jump_to_selected true if viewer should present a "jump to selected" checkbox.
+ */
ControlFilmViewer::ControlFilmViewer (wxWindow* parent, bool outline_content, bool jump_to_selected)
: wxPanel (parent)
- , _viewer (new FilmViewer(this, outline_content, jump_to_selected))
+ , _viewer (new FilmViewer(this))
+ , _slider_being_moved (false)
+ , _was_running_before_slider (false)
+ , _outline_content (0)
+ , _eye (0)
+ , _jump_to_selected (0)
, _slider (new wxSlider (this, wxID_ANY, 0, 0, 4096))
, _rewind_button (new wxButton (this, wxID_ANY, wxT("|<")))
, _back_button (new wxButton (this, wxID_ANY, wxT("<")))
_back_button->SetMinSize (wxSize (32, -1));
_forward_button->SetMinSize (wxSize (32, -1));
- _eye->Bind (wxEVT_CHOICE, boost::bind (&FilmViewer::slow_refresh, _viewer.get()));
+ _eye->Bind (wxEVT_CHOICE, boost::bind (&ControlFilmViewer::eye_changed, this));
+ if (_outline_content) {
+ _outline_content->Bind (wxEVT_CHECKBOX, boost::bind (&ControlFilmViewer::outline_content_changed, this));
+ }
+
_slider->Bind (wxEVT_SCROLL_THUMBTRACK, boost::bind (&ControlFilmViewer::slider_moved, this, false));
_slider->Bind (wxEVT_SCROLL_PAGEUP, boost::bind (&ControlFilmViewer::slider_moved, this, true));
_slider->Bind (wxEVT_SCROLL_PAGEDOWN, boost::bind (&ControlFilmViewer::slider_moved, this, true));
_jump_to_selected->Bind (wxEVT_CHECKBOX, boost::bind (&ControlFilmViewer::jump_to_selected_clicked, this));
_jump_to_selected->SetValue (Config::instance()->jump_to_selected ());
}
+
+ _viewer->ImageChanged.connect (boost::bind(&ControlFilmViewer::image_changed, this, _1));
+ _viewer->PositionChanged.connect (boost::bind(&ControlFilmViewer::position_changed, this));
+
+ set_film (shared_ptr<Film> ());
+
+ setup_sensitivity ();
+
+ JobManager::instance()->ActiveJobsChanged.connect (
+ bind (&ControlFilmViewer::active_jobs_changed, this, _2)
+ );
+
+ _film->Change.connect (boost::bind (&ControlFilmViewer::film_change, this, _1, _2));
+}
+
+void
+ControlFilmViewer::position_changed ()
+{
+ update_position_label ();
+ update_position_slider ();
+}
+
+void
+ControlFilmViewer::eye_changed ()
+{
+ _viewer->set_eyes (_eye->GetSelection() == 0 ? EYES_LEFT : EYES_RIGHT);
+}
+
+void
+ControlFilmViewer::outline_content_changed ()
+{
+ _viewer->set_outline_content (_outline_content->GetValue());
+}
+
+void
+ControlFilmViewer::film_change (ChangeType type, Film::Property p)
+{
+ if (type != CHANGE_TYPE_DONE) {
+ return;
+ }
+
+ if (p == Film::CONTENT || p == Film::THREE_D) {
+ setup_sensitivity ();
+ }
+}
+
+void
+ControlFilmViewer::image_changed (weak_ptr<PlayerVideo> pv)
+{
+ ImageChanged (pv);
}
/** @param page true if this was a PAGEUP/PAGEDOWN event for which we won't receive a THUMBRELEASE */
_film = film;
+ setup_sensitivity ();
+
update_position_slider ();
update_position_label ();
}
void
ControlFilmViewer::start ()
{
+ _play_button->SetValue (true);
_viewer->start ();
}
bool
ControlFilmViewer::stop ()
{
+ _play_button->SetValue (false);
return _viewer->stop ();
}
{
return _viewer->playing ();
}
+
+void
+ControlFilmViewer::slow_refresh ()
+{
+ _viewer->slow_refresh ();
+}
+
+int
+ControlFilmViewer::dropped () const
+{
+ return _viewer->dropped ();
+}
+
+shared_ptr<Film>
+ControlFilmViewer::film () const
+{
+ return _film;
+}
+
+optional<int>
+ControlFilmViewer::dcp_decode_reduction () const
+{
+ return _viewer->dcp_decode_reduction ();
+}
+
+DCPTime
+ControlFilmViewer::position () const
+{
+ return _viewer->position ();
+}
+
+void
+ControlFilmViewer::set_coalesce_player_changes (bool c)
+{
+ _viewer->set_coalesce_player_changes (c);
+}
#include "lib/dcpomatic_time.h"
+#include "lib/types.h"
+#include "lib/film.h"
#include <wx/wx.h>
#include <boost/shared_ptr.hpp>
+#include <boost/signals2.hpp>
class FilmViewer;
class Film;
class ClosedCaptionsDialog;
class Content;
+class PlayerVideo;
class wxToggleButton;
class ControlFilmViewer : public wxPanel
ControlFilmViewer (wxWindow* parent, bool outline_content = true, bool jump_to_selected = true);
void set_film (boost::shared_ptr<Film> film);
+ void back_frame ();
+ void forward_frame ();
/* FilmViewer proxies */
void set_position (DCPTime p);
void start ();
bool stop ();
bool playing () const;
- void back_frame ();
- void forward_frame ();
+ void slow_refresh ();
+ int dropped () const;
+ boost::shared_ptr<Film> film () const;
+ boost::optional<int> dcp_decode_reduction () const;
+ DCPTime position () const;
+ void set_coalesce_player_changes (bool c);
+ boost::signals2::signal<void (boost::weak_ptr<PlayerVideo>)> ImageChanged;
private:
void update_position_label ();
void timecode_clicked ();
void check_play_state ();
void active_jobs_changed (boost::optional<std::string>);
+ DCPTime nudge_amount (wxKeyboardState& ev);
+ void image_changed (boost::weak_ptr<PlayerVideo>);
+ void film_change (ChangeType type, Film::Property p);
+ void outline_content_changed ();
+ void eye_changed ();
+ void position_changed ();
boost::shared_ptr<Film> _film;
boost::shared_ptr<FilmViewer> _viewer;
return reinterpret_cast<FilmViewer*>(data)->audio_callback (out, frames);
}
-FilmViewer::FilmViewer (wxWindow* p, bool outline_content, bool jump_to_selected)
+FilmViewer::FilmViewer (wxWindow* p)
: _panel (new wxPanel (p))
- , _outline_content (0)
- , _eye (0)
- , _jump_to_selected (0)
, _coalesce_player_changes (false)
- , _slider_being_moved (false)
- , _was_running_before_slider (false)
, _audio (DCPOMATIC_RTAUDIO_API)
, _audio_channels (0)
, _audio_block_size (1024)
, _playing (false)
, _latency_history_count (0)
, _dropped (0)
- , _closed_captions_dialog (new ClosedCaptionsDialog(GetParent()))
+ , _closed_captions_dialog (new ClosedCaptionsDialog(p))
+ , _outline_content (false)
+ , _eyes (EYES_LEFT)
{
#ifndef __WXOSX__
_panel->SetDoubleBuffered (true);
_panel->Bind (wxEVT_PAINT, boost::bind (&FilmViewer::paint_panel, this));
_panel->Bind (wxEVT_SIZE, boost::bind (&FilmViewer::panel_sized, this, _1));
- if (_outline_content) {
- _outline_content->Bind (wxEVT_CHECKBOX, boost::bind (&FilmViewer::refresh_panel, this));
- }
_timer.Bind (wxEVT_TIMER, boost::bind (&FilmViewer::timer, this));
set_film (shared_ptr<Film> ());
- JobManager::instance()->ActiveJobsChanged.connect (
- bind (&FilmViewer::active_jobs_changed, this, _2)
- );
-
- setup_sensitivity ();
-
_config_changed_connection = Config::instance()->Changed.connect (bind (&FilmViewer::config_changed, this, _1));
config_changed (Config::SOUND_OUTPUT);
}
_player->set_dcp_decode_reduction (_dcp_decode_reduction);
}
} catch (bad_alloc) {
- error_dialog (this, _("There is not enough free memory to do that."));
+ error_dialog (_panel, _("There is not enough free memory to do that."));
_film.reset ();
return;
}
calculate_sizes ();
slow_refresh ();
-
- setup_sensitivity ();
}
void
} while (
_player_video.first &&
_film->three_d() &&
- ((_eye->GetSelection() == 0 && _player_video.first->eyes() == EYES_RIGHT) || (_eye->GetSelection() == 1 && _player_video.first->eyes() == EYES_LEFT))
+ (_eyes != _player_video.first->eyes())
);
_butler->rethrow ();
}
get ();
- update_position_label ();
- update_position_slider ();
+ PositionChanged ();
DCPTime const next = _video_position + one_video_frame();
if (next >= _film->length()) {
dc.DrawBitmap (frame_bitmap, 0, 0);
if (_out_size.width < _panel_size.width) {
- wxPen p (GetBackgroundColour ());
- wxBrush b (GetBackgroundColour ());
+ wxPen p (_panel->GetParent()->GetBackgroundColour());
+ wxBrush b (_panel->GetParent()->GetBackgroundColour());
dc.SetPen (p);
dc.SetBrush (b);
dc.DrawRectangle (_out_size.width, 0, _panel_size.width - _out_size.width, _panel_size.height);
}
if (_out_size.height < _panel_size.height) {
- wxPen p (GetBackgroundColour ());
- wxBrush b (GetBackgroundColour ());
+ wxPen p (_panel->GetParent()->GetBackgroundColour());
+ wxBrush b (_panel->GetParent()->GetBackgroundColour());
dc.SetPen (p);
dc.SetBrush (b);
dc.DrawRectangle (0, _out_size.height, _panel_size.width, _panel_size.height - _out_size.height);
}
- if (_outline_content && _outline_content->GetValue ()) {
+ if (_outline_content) {
wxPen p (wxColour (255, 0, 0), 2);
dc.SetPen (p);
dc.SetBrush (*wxTRANSPARENT_BRUSH);
}
}
+void
+FilmViewer::set_outline_content (bool o)
+{
+ _outline_content = o;
+ refresh_panel ();
+}
+
+void
+FilmViewer::set_eyes (Eyes e)
+{
+ _eyes = e;
+ slow_refresh ();
+}
+
void
FilmViewer::panel_sized (wxSizeEvent& ev)
{
if (!quick_refresh()) {
slow_refresh ();
}
- update_position_label ();
- update_position_slider ();
+ PositionChanged ();
}
void
_playing = true;
_dropped = 0;
timer ();
- _play_button->SetValue (true);
}
bool
}
_playing = false;
- _play_button->SetValue (false);
return true;
}
}
seek (t, true);
- update_position_label ();
- update_position_slider ();
+ PositionChanged ();
}
void
if (!refreshed) {
slow_refresh ();
}
- update_position_label ();
- update_position_slider ();
+ PositionChanged ();
}
void
FilmViewer::film_change (ChangeType type, Film::Property p)
{
- if (type != CHANGE_TYPE_DONE) {
- return;
- }
-
- if (p == Film::CONTENT || p == Film::THREE_D) {
- setup_sensitivity ();
- } else if (p == Film::AUDIO_CHANNELS) {
+ if (type == CHANGE_TYPE_DONE && p == Film::AUDIO_CHANNELS) {
recreate_butler ();
}
}
{
_video_position = p;
seek (p, true);
- update_position_label ();
- update_position_slider ();
+ PositionChanged ();
}
void
} catch (RtAudioError& e) {
#endif
error_dialog (
- this,
+ _panel,
_("Could not set up audio output. There will be no audio during the preview."), std_to_wx(e.what())
);
}
}
void
-FilmViewer::back_frame (DCPTime by)
+FilmViewer::move (DCPTime by)
{
if (!_film) {
return;
class FilmViewer
{
public:
- FilmViewer (wxWindow *, bool outline_content = true, bool jump_to_selected = true);
+ FilmViewer (wxWindow *);
~FilmViewer ();
wxPanel* panel () const {
DCPTime video_position () const {
return _video_position;
}
+ void go_to (DCPTime t);
+ void set_outline_content (bool o);
+ void set_eyes (Eyes e);
int audio_callback (void* out, unsigned int frames);
void show_closed_captions ();
boost::signals2::signal<void (boost::weak_ptr<PlayerVideo>)> ImageChanged;
+ boost::signals2::signal<void ()> PositionChanged;
private:
void paint_panel ();
void player_change (ChangeType type, int, bool);
void get ();
void display_player_video ();
- void refresh_panel ();
void film_change (ChangeType, Film::Property);
- DCPTime nudge_amount (wxKeyboardState &);
void timecode_clicked ();
- void go_to (DCPTime t);
void recreate_butler ();
void config_changed (Config::Property);
DCPTime time () const;
DCPTime uncorrected_time () const;
Frame average_latency () const;
+ void refresh_panel ();
boost::shared_ptr<Film> _film;
boost::shared_ptr<Player> _player;
ClosedCaptionsDialog* _closed_captions_dialog;
+ bool _outline_content;
+ Eyes _eyes;
+
boost::signals2::scoped_connection _config_changed_connection;
};
#include "player_information.h"
#include "wx_util.h"
-#include "film_viewer.h"
+#include "control_film_viewer.h"
#include "lib/playlist.h"
#include "lib/compose.hpp"
#include "lib/video_content.h"
#include "lib/audio_content.h"
#include "lib/dcp_content.h"
+#include "lib/film.h"
using std::cout;
using std::string;
#include <wx/wx.h>
#include <boost/scoped_ptr.hpp>
-class FilmViewer;
+class ControlFilmViewer;
class PlayerInformation : public wxPanel
{
#include "timing_panel.h"
#include "wx_util.h"
-#include "film_viewer.h"
+#include "control_film_viewer.h"
#include "timecode.h"
#include "content_panel.h"
#include "move_to_dialog.h"
#include "content_sub_panel.h"
#include "timecode.h"
-class FilmViewer;
+class ControlFilmViewer;
class TimingPanel : public ContentSubPanel
{
/*
- Copyright (C) 2015 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2015-2018 Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
#include "video_waveform_dialog.h"
#include "video_waveform_plot.h"
-#include "film_viewer.h"
+#include "control_film_viewer.h"
#include "wx_util.h"
#include <boost/bind.hpp>
#include <iostream>
#include "control_film_viewer.h"
#include "wx_util.h"
#include "lib/image.h"
+#include "lib/film.h"
#include "lib/dcp_video.h"
#include <dcp/locale_convert.h>
#include <dcp/openjpeg_image.h>
class PlayerVideo;
class Image;
class Film;
-class FilmViewer;
+class ControlFilmViewer;
class VideoWaveformPlot : public wxPanel
{