summaryrefslogtreecommitdiff
path: root/src/wx
diff options
context:
space:
mode:
Diffstat (limited to 'src/wx')
-rw-r--r--src/wx/about_dialog.cc10
-rw-r--r--src/wx/about_dialog.h11
-rw-r--r--src/wx/audio_mapping_view.cc25
-rw-r--r--src/wx/audio_mapping_view.h9
-rw-r--r--src/wx/audio_panel.cc2
-rw-r--r--src/wx/config_dialog.cc6
-rw-r--r--src/wx/content_widget.h9
-rw-r--r--src/wx/film_editor.cc2
-rw-r--r--src/wx/film_viewer.cc141
-rw-r--r--src/wx/film_viewer.h27
-rw-r--r--src/wx/properties_dialog.cc10
-rw-r--r--src/wx/screen_dialog.cc12
-rw-r--r--src/wx/screen_dialog.h8
-rw-r--r--src/wx/subtitle_panel.cc30
-rw-r--r--src/wx/subtitle_panel.h6
-rw-r--r--src/wx/subtitle_view.cc80
-rw-r--r--src/wx/subtitle_view.h33
-rw-r--r--src/wx/timecode.cc16
-rw-r--r--src/wx/timecode.h4
-rw-r--r--src/wx/timeline.cc100
-rw-r--r--src/wx/timeline.h10
-rw-r--r--src/wx/timing_panel.cc27
-rw-r--r--src/wx/video_panel.cc10
-rw-r--r--src/wx/video_panel.h9
-rw-r--r--src/wx/wscript1
-rw-r--r--src/wx/wx_ui_signaller.cc2
-rw-r--r--src/wx/wx_ui_signaller.h6
-rw-r--r--src/wx/wx_util.cc4
28 files changed, 380 insertions, 230 deletions
diff --git a/src/wx/about_dialog.cc b/src/wx/about_dialog.cc
index fe2c8d7ab..276f5507a 100644
--- a/src/wx/about_dialog.cc
+++ b/src/wx/about_dialog.cc
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2013-2014 Carl Hetherington <cth@carlh.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -17,6 +17,10 @@
*/
+/** @file src/wx/about_dialog.cc
+ * @brief The "about DCP-o-matic" dialogue box.
+ */
+
#include <wx/notebook.h>
#include <wx/hyperlink.h>
#include "lib/version.h"
@@ -202,6 +206,10 @@ AboutDialog::AboutDialog (wxWindow* parent)
SetSizerAndFit (overall_sizer);
}
+/** Add a section of credits.
+ * @param name Name of section.
+ * @param credits List of names.
+ */
void
AboutDialog::add_section (wxString name, wxArrayString credits)
{
diff --git a/src/wx/about_dialog.h b/src/wx/about_dialog.h
index a78abb93e..4901cf990 100644
--- a/src/wx/about_dialog.h
+++ b/src/wx/about_dialog.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2013-2014 Carl Hetherington <cth@carlh.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -17,10 +17,17 @@
*/
+/** @file src/wx/about_dialog.h
+ * @brief The "about DCP-o-matic" dialogue box.
+ */
+
#include <wx/wx.h>
class wxNotebook;
+/** @class AboutDialog
+ * @brief The "about DCP-o-matic" dialogue box.
+ */
class AboutDialog : public wxDialog
{
public:
@@ -29,6 +36,6 @@ public:
private:
void add_section (wxString, wxArrayString);
- wxNotebook* _notebook;
+ wxNotebook* _notebook; ///< notebook used to keep each list of names for the credits
};
diff --git a/src/wx/audio_mapping_view.cc b/src/wx/audio_mapping_view.cc
index 7fdecb8d5..be1bd67b9 100644
--- a/src/wx/audio_mapping_view.cc
+++ b/src/wx/audio_mapping_view.cc
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2013-2014 Carl Hetherington <cth@carlh.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -17,10 +17,14 @@
*/
+/** @file src/wx/audio_mapping_view.cc
+ * @brief AudioMappingView class and helpers.
+ */
+
#include <wx/wx.h>
#include <wx/renderer.h>
#include <wx/grid.h>
-#include <libdcp/types.h>
+#include <dcp/types.h>
#include "lib/audio_mapping.h"
#include "lib/util.h"
#include "audio_mapping_view.h"
@@ -52,6 +56,9 @@ public:
}
};
+/** @class ValueRenderer
+ * @brief wxGridCellRenderer for a gain value.
+ */
class ValueRenderer : public wxGridCellRenderer
{
public:
@@ -156,7 +163,7 @@ AudioMappingView::left_click (wxGridEvent& ev)
return;
}
- libdcp::Channel d = static_cast<libdcp::Channel> (ev.GetCol() - 1);
+ dcp::Channel d = static_cast<dcp::Channel> (ev.GetCol() - 1);
if (_map.get (ev.GetRow(), d) > 0) {
_map.set (ev.GetRow(), d, 0);
@@ -182,28 +189,28 @@ AudioMappingView::right_click (wxGridEvent& ev)
void
AudioMappingView::off ()
{
- _map.set (_menu_row, static_cast<libdcp::Channel> (_menu_column - 1), 0);
+ _map.set (_menu_row, static_cast<dcp::Channel> (_menu_column - 1), 0);
map_changed ();
}
void
AudioMappingView::full ()
{
- _map.set (_menu_row, static_cast<libdcp::Channel> (_menu_column - 1), 1);
+ _map.set (_menu_row, static_cast<dcp::Channel> (_menu_column - 1), 1);
map_changed ();
}
void
AudioMappingView::minus3dB ()
{
- _map.set (_menu_row, static_cast<libdcp::Channel> (_menu_column - 1), 1 / sqrt (2));
+ _map.set (_menu_row, static_cast<dcp::Channel> (_menu_column - 1), 1 / sqrt (2));
map_changed ();
}
void
AudioMappingView::edit ()
{
- libdcp::Channel d = static_cast<libdcp::Channel> (_menu_column - 1);
+ dcp::Channel d = static_cast<dcp::Channel> (_menu_column - 1);
AudioGainDialog* dialog = new AudioGainDialog (this, _menu_row, _menu_column - 1, _map.get (_menu_row, d));
if (dialog->ShowModal () == wxID_OK) {
@@ -242,7 +249,7 @@ AudioMappingView::update_cells ()
_grid->SetCellValue (i, 0, wxString::Format (wxT("%d"), i + 1));
for (int j = 1; j < _grid->GetNumberCols(); ++j) {
- _grid->SetCellValue (i, j, std_to_wx (lexical_cast<string> (_map.get (i, static_cast<libdcp::Channel> (j - 1)))));
+ _grid->SetCellValue (i, j, std_to_wx (lexical_cast<string> (_map.get (i, static_cast<dcp::Channel> (j - 1)))));
}
}
@@ -346,7 +353,7 @@ AudioMappingView::mouse_moved (wxMouseEvent& ev)
if (row != _last_tooltip_row || column != _last_tooltip_column) {
wxString s;
- float const gain = _map.get (row, static_cast<libdcp::Channel> (column - 1));
+ float const gain = _map.get (row, static_cast<dcp::Channel> (column - 1));
if (gain == 0) {
s = wxString::Format (_("No audio will be passed from content channel %d to DCP channel %d."), row + 1, column);
} else if (gain == 1) {
diff --git a/src/wx/audio_mapping_view.h b/src/wx/audio_mapping_view.h
index 26f1746e0..3d8db0cff 100644
--- a/src/wx/audio_mapping_view.h
+++ b/src/wx/audio_mapping_view.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2013-2014 Carl Hetherington <cth@carlh.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -17,6 +17,13 @@
*/
+/** @file src/wx/audio_mapping_view.h
+ * @brief AudioMappingView class
+ *
+ * This class displays the mapping of one set of audio channels to another,
+ * with gain values on each node of the map.
+ */
+
#include <boost/signals2.hpp>
#include <wx/wx.h>
#include <wx/grid.h>
diff --git a/src/wx/audio_panel.cc b/src/wx/audio_panel.cc
index 1c679d336..eb95e17ab 100644
--- a/src/wx/audio_panel.cc
+++ b/src/wx/audio_panel.cc
@@ -237,7 +237,7 @@ AudioPanel::setup_stream_description ()
} else {
s << fcs->audio_channels() << wxT (" ") << _("channels");
}
- s << wxT (", ") << fcs->content_audio_frame_rate() << _("Hz");
+ s << wxT (", ") << fcs->audio_frame_rate() << _("Hz");
_description->SetLabel (s);
}
}
diff --git a/src/wx/config_dialog.cc b/src/wx/config_dialog.cc
index e7133a534..799067920 100644
--- a/src/wx/config_dialog.cc
+++ b/src/wx/config_dialog.cc
@@ -28,7 +28,7 @@
#include <wx/preferences.h>
#include <wx/filepicker.h>
#include <wx/spinctrl.h>
-#include <libdcp/colour_matrix.h>
+#include <dcp/colour_matrix.h>
#include "lib/config.h"
#include "lib/ratio.h"
#include "lib/scaler.h"
@@ -460,14 +460,14 @@ private:
void issuer_changed ()
{
- libdcp::XMLMetadata m = Config::instance()->dcp_metadata ();
+ dcp::XMLMetadata m = Config::instance()->dcp_metadata ();
m.issuer = wx_to_std (_issuer->GetValue ());
Config::instance()->set_dcp_metadata (m);
}
void creator_changed ()
{
- libdcp::XMLMetadata m = Config::instance()->dcp_metadata ();
+ dcp::XMLMetadata m = Config::instance()->dcp_metadata ();
m.creator = wx_to_std (_creator->GetValue ());
Config::instance()->set_dcp_metadata (m);
}
diff --git a/src/wx/content_widget.h b/src/wx/content_widget.h
index 30501c1a9..8b7616044 100644
--- a/src/wx/content_widget.h
+++ b/src/wx/content_widget.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2013-2014 Carl Hetherington <cth@carlh.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -17,6 +17,10 @@
*/
+/** @file src/wx/content_widget.h
+ * @brief ContentWidget class.
+ */
+
#ifndef DCPOMATIC_MULTIPLE_WIDGET_H
#define DCPOMATIC_MULTIPLE_WIDGET_H
@@ -26,7 +30,8 @@
#include <boost/function.hpp>
#include "wx_util.h"
-/** A widget which represents some Content state and which can be used
+/** @class ContentWidget
+ * @brief A widget which represents some Content state and which can be used
* when multiple pieces of content are selected.
*
* @param S Type containing the content being represented (e.g. VideoContent)
diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc
index 1131675bc..2cf6a0b6c 100644
--- a/src/wx/film_editor.cc
+++ b/src/wx/film_editor.cc
@@ -854,7 +854,7 @@ FilmEditor::setup_content_sensitivity ()
_video_panel->Enable (video_selection.size() > 0 && _generally_sensitive);
_audio_panel->Enable (audio_selection.size() > 0 && _generally_sensitive);
- _subtitle_panel->Enable (selection.size() == 1 && dynamic_pointer_cast<FFmpegContent> (selection.front()) && _generally_sensitive);
+ _subtitle_panel->Enable (selection.size() == 1 && dynamic_pointer_cast<SubtitleContent> (selection.front()) && _generally_sensitive);
_timing_panel->Enable (selection.size() == 1 && _generally_sensitive);
}
diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc
index ce5eab00e..e517c9cca 100644
--- a/src/wx/film_viewer.cc
+++ b/src/wx/film_viewer.cc
@@ -36,6 +36,8 @@
#include "lib/player.h"
#include "lib/video_content.h"
#include "lib/video_decoder.h"
+#include "lib/timer.h"
+#include "lib/dcp_video.h"
#include "film_viewer.h"
#include "wx_util.h"
@@ -50,7 +52,7 @@ using std::make_pair;
using boost::shared_ptr;
using boost::dynamic_pointer_cast;
using boost::weak_ptr;
-using libdcp::Size;
+using dcp::Size;
FilmViewer::FilmViewer (shared_ptr<Film> f, wxWindow* p)
: wxPanel (p)
@@ -61,7 +63,6 @@ FilmViewer::FilmViewer (shared_ptr<Film> f, wxWindow* p)
, _frame_number (new wxStaticText (this, wxID_ANY, wxT("")))
, _timecode (new wxStaticText (this, wxID_ANY, wxT("")))
, _play_button (new wxToggleButton (this, wxID_ANY, _("Play")))
- , _got_frame (false)
{
#ifndef __WXOSX__
_panel->SetDoubleBuffered (true);
@@ -121,7 +122,7 @@ FilmViewer::set_film (shared_ptr<Film> f)
_frame.reset ();
_slider->SetValue (0);
- set_position_text (0);
+ set_position_text ();
if (!_film) {
return;
@@ -135,30 +136,31 @@ FilmViewer::set_film (shared_ptr<Film> f)
return;
}
- _player->disable_audio ();
- _player->Video.connect (boost::bind (&FilmViewer::process_video, this, _1, _2, _5));
+ _player->set_approximate_size ();
_player->Changed.connect (boost::bind (&FilmViewer::player_changed, this, _1));
calculate_sizes ();
- fetch_next_frame ();
+ get (_position, true);
}
void
-FilmViewer::fetch_current_frame_again ()
+FilmViewer::get (DCPTime p, bool accurate)
{
if (!_player) {
return;
}
- /* We could do this with a seek and a fetch_next_frame, but this is
- a shortcut to make it quicker.
- */
-
- _got_frame = false;
- if (!_player->repeat_last_video ()) {
- fetch_next_frame ();
+ list<shared_ptr<DCPVideo> > dcp_video = _player->get_video (p, accurate);
+ if (!dcp_video.empty ()) {
+ _frame = dcp_video.front()->image (PIX_FMT_BGRA, true);
+ _frame = _frame->scale (_frame->size(), Scaler::from_id ("fastbilinear"), PIX_FMT_RGB24, false);
+ } else {
+ _frame.reset ();
}
+
+ _position = p;
+ set_position_text ();
_panel->Refresh ();
_panel->Update ();
}
@@ -166,16 +168,12 @@ FilmViewer::fetch_current_frame_again ()
void
FilmViewer::timer ()
{
- if (!_player) {
- return;
- }
-
- fetch_next_frame ();
+ get (_position + DCPTime::from_frames (1, _film->video_frame_rate ()), true);
- Time const len = _film->length ();
+ DCPTime const len = _film->length ();
- if (len) {
- int const new_slider_position = 4096 * _player->video_position() / len;
+ if (len.get ()) {
+ int const new_slider_position = 4096 * _position.get() / len.get();
if (new_slider_position != _slider->GetValue()) {
_slider->SetValue (new_slider_position);
}
@@ -218,15 +216,16 @@ FilmViewer::paint_panel ()
void
FilmViewer::slider_moved ()
{
- if (_film && _player) {
- Time t = _slider->GetValue() * _film->length() / 4096;
- /* Ensure that we hit the end of the film at the end of the slider */
- if (t >= _film->length ()) {
- t = _film->length() - _film->video_frames_to_time (1);
- }
- _player->seek (t, false);
- fetch_next_frame ();
+ if (!_film) {
+ return;
+ }
+
+ DCPTime t (_slider->GetValue() * _film->length().get() / 4096);
+ /* Ensure that we hit the end of the film at the end of the slider */
+ if (t >= _film->length ()) {
+ t = _film->length() - DCPTime::from_frames (1, _film->video_frame_rate ());
}
+ get (t, false);
}
void
@@ -235,7 +234,7 @@ FilmViewer::panel_sized (wxSizeEvent& ev)
_panel_size.width = ev.GetSize().GetWidth();
_panel_size.height = ev.GetSize().GetHeight();
calculate_sizes ();
- fetch_current_frame_again ();
+ get (_position, true);
}
void
@@ -264,6 +263,13 @@ FilmViewer::calculate_sizes ()
_out_size.width = max (64, _out_size.width);
_out_size.height = max (64, _out_size.height);
+ /* The player will round its image down to the nearest 4 pixels
+ to speed up its scale, so do similar here to avoid black borders
+ around things. This is a bit of a hack.
+ */
+ _out_size.width &= ~3;
+ _out_size.height &= ~3;
+
_player->set_video_container_size (_out_size);
}
@@ -288,20 +294,7 @@ FilmViewer::check_play_state ()
}
void
-FilmViewer::process_video (shared_ptr<PlayerImage> image, Eyes eyes, Time t)
-{
- if (eyes == EYES_RIGHT) {
- return;
- }
-
- _frame = image->image ();
- _got_frame = true;
-
- set_position_text (t);
-}
-
-void
-FilmViewer::set_position_text (Time t)
+FilmViewer::set_position_text ()
{
if (!_film) {
_frame_number->SetLabel ("0");
@@ -311,9 +304,9 @@ FilmViewer::set_position_text (Time t)
double const fps = _film->video_frame_rate ();
/* Count frame number from 1 ... not sure if this is the best idea */
- _frame_number->SetLabel (wxString::Format (wxT("%d"), int (rint (t * fps / TIME_HZ)) + 1));
+ _frame_number->SetLabel (wxString::Format (wxT("%d"), int (rint (_position.seconds() * fps)) + 1));
- double w = static_cast<double>(t) / TIME_HZ;
+ double w = _position.seconds ();
int const h = (w / 3600);
w -= h * 3600;
int const m = (w / 60);
@@ -324,35 +317,6 @@ FilmViewer::set_position_text (Time t)
_timecode->SetLabel (wxString::Format (wxT("%02d:%02d:%02d.%02d"), h, m, s, f));
}
-/** Ask the player to emit its next frame, then update our display */
-void
-FilmViewer::fetch_next_frame ()
-{
- /* Clear our frame in case we don't get a new one */
- _frame.reset ();
-
- if (!_player) {
- return;
- }
-
- _got_frame = false;
-
- try {
- while (!_got_frame && !_player->pass ()) {}
- } catch (DecodeError& e) {
- _play_button->SetValue (false);
- check_play_state ();
- error_dialog (this, wxString::Format (_("Could not decode video for view (%s)"), std_to_wx(e.what()).data()));
- } catch (OpenFileError& e) {
- /* There was a problem opening a content file; we'll let this slide as it
- probably means a missing content file, which we're already taking care of.
- */
- }
-
- _panel->Refresh ();
- _panel->Update ();
-}
-
void
FilmViewer::active_jobs_changed (bool a)
{
@@ -376,31 +340,18 @@ FilmViewer::active_jobs_changed (bool a)
void
FilmViewer::back_clicked ()
{
- if (!_player) {
- return;
+ DCPTime p = _position - DCPTime::from_frames (1, _film->video_frame_rate ());
+ if (p < DCPTime ()) {
+ p = DCPTime ();
}
- /* Player::video_position is the time after the last frame that we received.
- We want to see the one before it, so we need to go back 2.
- */
-
- Time p = _player->video_position() - _film->video_frames_to_time (2);
- if (p < 0) {
- p = 0;
- }
-
- _player->seek (p, true);
- fetch_next_frame ();
+ get (p, true);
}
void
FilmViewer::forward_clicked ()
{
- if (!_player) {
- return;
- }
-
- fetch_next_frame ();
+ get (_position + DCPTime::from_frames (1, _film->video_frame_rate ()), true);
}
void
@@ -411,5 +362,5 @@ FilmViewer::player_changed (bool frequent)
}
calculate_sizes ();
- fetch_current_frame_again ();
+ get (_position, true);
}
diff --git a/src/wx/film_viewer.h b/src/wx/film_viewer.h
index c99c73440..207004f29 100644
--- a/src/wx/film_viewer.h
+++ b/src/wx/film_viewer.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2012 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2012-2014 Carl Hetherington <cth@carlh.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -32,19 +32,6 @@ class PlayerImage;
/** @class FilmViewer
* @brief A wx widget to view a preview of a Film.
- *
- * The film takes the following path through the viewer:
- *
- * 1. fetch_next_frame() asks our _player to decode some data. If it does, process_video()
- * will be called.
- *
- * 2. process_video() takes the image from the player (_frame).
- *
- * 3. fetch_next_frame() calls _panel->Refresh() and _panel->Update() which results in
- * paint_panel() being called; this creates frame_bitmap from _frame and blits it to the display.
- *
- * fetch_current_frame_again() asks the player to re-emit its current frame on the next pass(), and then
- * starts from step #1.
*/
class FilmViewer : public wxPanel
{
@@ -59,16 +46,14 @@ private:
void slider_moved ();
void play_clicked ();
void timer ();
- void process_video (boost::shared_ptr<PlayerImage>, Eyes, Time);
void calculate_sizes ();
void check_play_state ();
- void fetch_current_frame_again ();
- void fetch_next_frame ();
void active_jobs_changed (bool);
void back_clicked ();
void forward_clicked ();
void player_changed (bool);
- void set_position_text (Time);
+ void set_position_text ();
+ void get (DCPTime, bool);
boost::shared_ptr<Film> _film;
boost::shared_ptr<Player> _player;
@@ -84,10 +69,10 @@ private:
wxTimer _timer;
boost::shared_ptr<const Image> _frame;
- bool _got_frame;
+ DCPTime _position;
/** Size of our output (including padding if we have any) */
- libdcp::Size _out_size;
+ dcp::Size _out_size;
/** Size of the panel that we have available */
- libdcp::Size _panel_size;
+ dcp::Size _panel_size;
};
diff --git a/src/wx/properties_dialog.cc b/src/wx/properties_dialog.cc
index 28247bc33..801996efa 100644
--- a/src/wx/properties_dialog.cc
+++ b/src/wx/properties_dialog.cc
@@ -45,8 +45,7 @@ PropertiesDialog::PropertiesDialog (wxWindow* parent, shared_ptr<Film> film)
add (_("Frames already encoded"), true);
_encoded = add (new ThreadedStaticText (this, _("counting..."), boost::bind (&PropertiesDialog::frames_already_encoded, this)));
_encoded->Finished.connect (boost::bind (&PropertiesDialog::layout, this));
-
- _frames->SetLabel (std_to_wx (lexical_cast<string> (_film->time_to_video_frames (_film->length()))));
+ _frames->SetLabel (std_to_wx (lexical_cast<string> (_film->length().frames (_film->video_frame_rate ()))));
double const disk = double (_film->required_disk_space()) / 1073741824.0f;
stringstream s;
s << fixed << setprecision (1) << disk << wx_to_std (_("Gb"));
@@ -64,10 +63,11 @@ PropertiesDialog::frames_already_encoded () const
} catch (boost::thread_interrupted &) {
return "";
}
-
- if (_film->length()) {
+
+ uint64_t const frames = _film->length().frames (_film->video_frame_rate ());
+ if (frames) {
/* XXX: encoded_frames() should check which frames have been encoded */
- u << " (" << (_film->encoded_frames() * 100 / _film->time_to_video_frames (_film->length())) << "%)";
+ u << " (" << (_film->encoded_frames() * 100 / frames) << "%)";
}
return u.str ();
}
diff --git a/src/wx/screen_dialog.cc b/src/wx/screen_dialog.cc
index b702ae0ad..0d46a46ec 100644
--- a/src/wx/screen_dialog.cc
+++ b/src/wx/screen_dialog.cc
@@ -19,7 +19,7 @@
#include <wx/filepicker.h>
#include <wx/validate.h>
-#include <libdcp/exceptions.h>
+#include <dcp/exceptions.h>
#include "lib/compose.hpp"
#include "lib/util.h"
#include "screen_dialog.h"
@@ -31,7 +31,7 @@ using std::string;
using std::cout;
using boost::shared_ptr;
-ScreenDialog::ScreenDialog (wxWindow* parent, string title, string name, shared_ptr<libdcp::Certificate> certificate)
+ScreenDialog::ScreenDialog (wxWindow* parent, string title, string name, shared_ptr<dcp::Certificate> certificate)
: TableDialog (parent, std_to_wx (title), 2, true)
, _certificate (certificate)
{
@@ -79,7 +79,7 @@ ScreenDialog::name () const
return wx_to_std (_name->GetValue());
}
-shared_ptr<libdcp::Certificate>
+shared_ptr<dcp::Certificate>
ScreenDialog::certificate () const
{
return _certificate;
@@ -89,9 +89,9 @@ void
ScreenDialog::load_certificate (boost::filesystem::path file)
{
try {
- _certificate.reset (new libdcp::Certificate (file));
+ _certificate.reset (new dcp::Certificate (file));
_certificate_text->SetValue (_certificate->certificate ());
- } catch (libdcp::MiscError& e) {
+ } catch (dcp::MiscError& e) {
error_dialog (this, String::compose ("Could not read certificate file (%1)", e.what()));
}
}
@@ -128,7 +128,7 @@ void
ScreenDialog::setup_sensitivity ()
{
wxButton* ok = dynamic_cast<wxButton*> (FindWindowById (wxID_OK, this));
- ok->Enable (_certificate);
+ ok->Enable (_certificate.get ());
_download_certificate->Enable (
_manufacturer->GetStringSelection() == _("Doremi") ||
diff --git a/src/wx/screen_dialog.h b/src/wx/screen_dialog.h
index 3601a8f6c..5c6d964b8 100644
--- a/src/wx/screen_dialog.h
+++ b/src/wx/screen_dialog.h
@@ -19,7 +19,7 @@
#include <wx/wx.h>
#include <boost/shared_ptr.hpp>
-#include <libdcp/certificates.h>
+#include <dcp/certificates.h>
#include "table_dialog.h"
class Progress;
@@ -27,10 +27,10 @@ class Progress;
class ScreenDialog : public TableDialog
{
public:
- ScreenDialog (wxWindow *, std::string, std::string name = "", boost::shared_ptr<libdcp::Certificate> c = boost::shared_ptr<libdcp::Certificate> ());
+ ScreenDialog (wxWindow *, std::string, std::string name = "", boost::shared_ptr<dcp::Certificate> c = boost::shared_ptr<dcp::Certificate> ());
std::string name () const;
- boost::shared_ptr<libdcp::Certificate> certificate () const;
+ boost::shared_ptr<dcp::Certificate> certificate () const;
private:
void select_certificate ();
@@ -44,5 +44,5 @@ private:
wxButton* _download_certificate;
wxTextCtrl* _certificate_text;
- boost::shared_ptr<libdcp::Certificate> _certificate;
+ boost::shared_ptr<dcp::Certificate> _certificate;
};
diff --git a/src/wx/subtitle_panel.cc b/src/wx/subtitle_panel.cc
index 63a18b0ce..b4b5a7b42 100644
--- a/src/wx/subtitle_panel.cc
+++ b/src/wx/subtitle_panel.cc
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2012-2013 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2012-2014 Carl Hetherington <cth@carlh.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -20,9 +20,11 @@
#include <boost/lexical_cast.hpp>
#include <wx/spinctrl.h>
#include "lib/ffmpeg_content.h"
+#include "lib/subrip_content.h"
#include "subtitle_panel.h"
#include "film_editor.h"
#include "wx_util.h"
+#include "subtitle_view.h"
using std::vector;
using std::string;
@@ -32,6 +34,7 @@ using boost::dynamic_pointer_cast;
SubtitlePanel::SubtitlePanel (FilmEditor* e)
: FilmEditorPanel (e, _("Subtitles"))
+ , _view (0)
{
wxFlexGridSizer* grid = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
_sizer->Add (grid, 0, wxALL, 8);
@@ -70,6 +73,9 @@ SubtitlePanel::SubtitlePanel (FilmEditor* e)
add_label_to_sizer (grid, this, _("Subtitle Stream"), true);
_stream = new wxChoice (this, wxID_ANY);
grid->Add (_stream, 1, wxEXPAND);
+
+ _view_button = new wxButton (this, wxID_ANY, _("View..."));
+ grid->Add (_view_button);
_x_offset->SetRange (-100, 100);
_y_offset->SetRange (-100, 100);
@@ -81,6 +87,7 @@ SubtitlePanel::SubtitlePanel (FilmEditor* e)
_y_offset->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&SubtitlePanel::y_offset_changed, this));
_scale->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&SubtitlePanel::scale_changed, this));
_stream->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&SubtitlePanel::stream_changed, this));
+ _view_button->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&SubtitlePanel::view_clicked, this));
}
void
@@ -164,6 +171,9 @@ SubtitlePanel::setup_sensitivity ()
_y_offset->Enable (j);
_scale->Enable (j);
_stream->Enable (j);
+
+ SubtitleContentList c = _editor->selected_subtitle_content ();
+ _view_button->Enable (c.size() == 1);
}
void
@@ -223,3 +233,21 @@ SubtitlePanel::content_selection_changed ()
film_content_changed (SubtitleContentProperty::SUBTITLE_Y_OFFSET);
film_content_changed (SubtitleContentProperty::SUBTITLE_SCALE);
}
+
+void
+SubtitlePanel::view_clicked ()
+{
+ if (_view) {
+ _view->Destroy ();
+ _view = 0;
+ }
+
+ SubtitleContentList c = _editor->selected_subtitle_content ();
+ assert (c.size() == 1);
+ shared_ptr<SubRipContent> sr = dynamic_pointer_cast<SubRipContent> (c.front ());
+ if (sr) {
+ _view = new SubtitleView (this, sr);
+ }
+
+ _view->Show ();
+}
diff --git a/src/wx/subtitle_panel.h b/src/wx/subtitle_panel.h
index 20d7c40c2..1ee775025 100644
--- a/src/wx/subtitle_panel.h
+++ b/src/wx/subtitle_panel.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2012-2013 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2012-2014 Carl Hetherington <cth@carlh.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -21,6 +21,7 @@
class wxCheckBox;
class wxSpinCtrl;
+class SubtitleView;
class SubtitlePanel : public FilmEditorPanel
{
@@ -37,6 +38,7 @@ private:
void y_offset_changed ();
void scale_changed ();
void stream_changed ();
+ void view_clicked ();
void setup_sensitivity ();
@@ -45,4 +47,6 @@ private:
wxSpinCtrl* _y_offset;
wxSpinCtrl* _scale;
wxChoice* _stream;
+ wxButton* _view_button;
+ SubtitleView* _view;
};
diff --git a/src/wx/subtitle_view.cc b/src/wx/subtitle_view.cc
new file mode 100644
index 000000000..adbc4a625
--- /dev/null
+++ b/src/wx/subtitle_view.cc
@@ -0,0 +1,80 @@
+/*
+ Copyright (C) 2014 Carl Hetherington <cth@carlh.net>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "lib/subrip_decoder.h"
+#include "lib/content_subtitle.h"
+#include "subtitle_view.h"
+
+using std::list;
+using boost::shared_ptr;
+using boost::dynamic_pointer_cast;
+
+SubtitleView::SubtitleView (wxWindow* parent, shared_ptr<SubRipContent> content)
+ : wxDialog (parent, wxID_ANY, _("Subtitles"))
+{
+ _list = new wxListCtrl (this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxLC_SINGLE_SEL);
+
+ {
+ wxListItem ip;
+ ip.SetId (0);
+ ip.SetText (_("Start"));
+ ip.SetWidth (100);
+ _list->InsertColumn (0, ip);
+ }
+
+ {
+ wxListItem ip;
+ ip.SetId (1);
+ ip.SetText (_("End"));
+ ip.SetWidth (100);
+ _list->InsertColumn (1, ip);
+ }
+
+ {
+ wxListItem ip;
+ ip.SetId (2);
+ ip.SetText (_("Subtitle"));
+ ip.SetWidth (640);
+ _list->InsertColumn (2, ip);
+ }
+
+ wxBoxSizer* sizer = new wxBoxSizer (wxVERTICAL);
+ sizer->Add (_list, 1, wxEXPAND);
+
+ wxSizer* buttons = CreateSeparatedButtonSizer (wxOK | wxCANCEL);
+ if (buttons) {
+ sizer->Add (buttons, wxSizerFlags().Expand().DoubleBorder());
+ }
+
+ shared_ptr<SubRipDecoder> decoder (new SubRipDecoder (content));
+ list<shared_ptr<ContentTextSubtitle> > subs = decoder->get_text_subtitles (ContentTime(), ContentTime::max ());
+ int n = 0;
+ for (list<shared_ptr<ContentTextSubtitle> >::const_iterator i = subs.begin(); i != subs.end(); ++i) {
+ for (list<dcp::SubtitleString>::const_iterator j = (*i)->subs.begin(); j != (*i)->subs.end(); ++j) {
+ wxListItem list_item;
+ list_item.SetId (n);
+ _list->InsertItem (list_item);
+ _list->SetItem (n, 2, j->text ());
+ ++n;
+ }
+ }
+
+ SetSizerAndFit (sizer);
+}
+
diff --git a/src/wx/subtitle_view.h b/src/wx/subtitle_view.h
new file mode 100644
index 000000000..94a25b70c
--- /dev/null
+++ b/src/wx/subtitle_view.h
@@ -0,0 +1,33 @@
+/*
+ Copyright (C) 2014 Carl Hetherington <cth@carlh.net>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <boost/shared_ptr.hpp>
+#include <wx/wx.h>
+#include <wx/listctrl.h>
+
+class SubRipContent;
+
+class SubtitleView : public wxDialog
+{
+public:
+ SubtitleView (wxWindow *, boost::shared_ptr<SubRipContent>);
+
+private:
+ wxListCtrl* _list;
+};
diff --git a/src/wx/timecode.cc b/src/wx/timecode.cc
index ee5b5604b..1ab4b590b 100644
--- a/src/wx/timecode.cc
+++ b/src/wx/timecode.cc
@@ -83,12 +83,12 @@ Timecode::Timecode (wxWindow* parent)
}
void
-Timecode::set (Time t, int fps)
+Timecode::set (DCPTime t, int fps)
{
/* Do this calculation with frames so that we can round
to a frame boundary at the start rather than the end.
*/
- int64_t f = divide_with_round (t * fps, TIME_HZ);
+ int64_t f = rint (t.seconds() * fps);
int const h = f / (3600 * fps);
f -= h * 3600 * fps;
@@ -105,18 +105,18 @@ Timecode::set (Time t, int fps)
_fixed->SetLabel (wxString::Format ("%02d:%02d:%02d.%02" wxLongLongFmtSpec "d", h, m, s, f));
}
-Time
+DCPTime
Timecode::get (int fps) const
{
- Time t = 0;
+ DCPTime t;
string const h = wx_to_std (_hours->GetValue ());
- t += lexical_cast<int> (h.empty() ? "0" : h) * 3600 * TIME_HZ;
+ t += DCPTime::from_seconds (lexical_cast<int> (h.empty() ? "0" : h) * 3600);
string const m = wx_to_std (_minutes->GetValue());
- t += lexical_cast<int> (m.empty() ? "0" : m) * 60 * TIME_HZ;
+ t += DCPTime::from_seconds (lexical_cast<int> (m.empty() ? "0" : m) * 60);
string const s = wx_to_std (_seconds->GetValue());
- t += lexical_cast<int> (s.empty() ? "0" : s) * TIME_HZ;
+ t += DCPTime::from_seconds (lexical_cast<int> (s.empty() ? "0" : s));
string const f = wx_to_std (_frames->GetValue());
- t += lexical_cast<int> (f.empty() ? "0" : f) * TIME_HZ / fps;
+ t += DCPTime::from_seconds (lexical_cast<double> (f.empty() ? "0" : f) / fps);
return t;
}
diff --git a/src/wx/timecode.h b/src/wx/timecode.h
index 880b44a31..b13e8c3c0 100644
--- a/src/wx/timecode.h
+++ b/src/wx/timecode.h
@@ -26,8 +26,8 @@ class Timecode : public wxPanel
public:
Timecode (wxWindow *);
- void set (Time, int);
- Time get (int) const;
+ void set (DCPTime, int);
+ DCPTime get (int) const;
void set_editable (bool);
diff --git a/src/wx/timeline.cc b/src/wx/timeline.cc
index 1858afee7..d5643b556 100644
--- a/src/wx/timeline.cc
+++ b/src/wx/timeline.cc
@@ -35,7 +35,9 @@ using boost::dynamic_pointer_cast;
using boost::bind;
using boost::optional;
-/** Parent class for components of the timeline (e.g. a piece of content or an axis) */
+/** @class View
+ * @brief Parent class for components of the timeline (e.g. a piece of content or an axis).
+ */
class View : public boost::noncopyable
{
public:
@@ -64,9 +66,9 @@ public:
protected:
virtual void do_paint (wxGraphicsContext *) = 0;
- int time_x (Time t) const
+ int time_x (DCPTime t) const
{
- return _timeline.tracks_position().x + t * _timeline.pixels_per_time_unit();
+ return _timeline.tracks_position().x + t.seconds() * _timeline.pixels_per_second ();
}
Timeline& _timeline;
@@ -76,7 +78,9 @@ private:
};
-/** Parent class for views of pieces of content */
+/** @class ContentView
+ * @brief Parent class for views of pieces of content.
+ */
class ContentView : public View
{
public:
@@ -101,7 +105,7 @@ public:
return dcpomatic::Rect<int> (
time_x (content->position ()) - 8,
y_pos (_track.get()) - 8,
- content->length_after_trim () * _timeline.pixels_per_time_unit() + 16,
+ content->length_after_trim().seconds() * _timeline.pixels_per_second() + 16,
_timeline.track_height() + 16
);
}
@@ -142,8 +146,8 @@ private:
return;
}
- Time const position = cont->position ();
- Time const len = cont->length_after_trim ();
+ DCPTime const position = cont->position ();
+ DCPTime const len = cont->length_after_trim ();
wxColour selected (colour().Red() / 2, colour().Green() / 2, colour().Blue() / 2);
@@ -172,7 +176,7 @@ private:
wxDouble name_leading;
gc->GetTextExtent (name, &name_width, &name_height, &name_descent, &name_leading);
- gc->Clip (wxRegion (time_x (position), y_pos (_track.get()), len * _timeline.pixels_per_time_unit(), _timeline.track_height()));
+ gc->Clip (wxRegion (time_x (position), y_pos (_track.get()), len.seconds() * _timeline.pixels_per_second(), _timeline.track_height()));
gc->DrawText (name, time_x (position) + 12, y_pos (_track.get() + 1) - name_height - 4);
gc->ResetClip ();
}
@@ -191,7 +195,7 @@ private:
}
if (!frequent) {
- _timeline.setup_pixels_per_time_unit ();
+ _timeline.setup_pixels_per_second ();
_timeline.Refresh ();
}
}
@@ -246,6 +250,25 @@ private:
}
};
+class SubtitleContentView : public ContentView
+{
+public:
+ SubtitleContentView (Timeline& tl, shared_ptr<Content> c)
+ : ContentView (tl, c)
+ {}
+
+private:
+ wxString type () const
+ {
+ return _("subtitles");
+ }
+
+ wxColour colour () const
+ {
+ return wxColour (163, 255, 154, 255);
+ }
+};
+
class TimeAxisView : public View
{
public:
@@ -271,18 +294,18 @@ private:
{
gc->SetPen (*wxThePenList->FindOrCreatePen (wxColour (0, 0, 0), 1, wxPENSTYLE_SOLID));
- int mark_interval = rint (128 / (TIME_HZ * _timeline.pixels_per_time_unit ()));
+ double mark_interval = rint (128 / _timeline.pixels_per_second ());
if (mark_interval > 5) {
- mark_interval -= mark_interval % 5;
+ mark_interval -= int (rint (mark_interval)) % 5;
}
if (mark_interval > 10) {
- mark_interval -= mark_interval % 10;
+ mark_interval -= int (rint (mark_interval)) % 10;
}
if (mark_interval > 60) {
- mark_interval -= mark_interval % 60;
+ mark_interval -= int (rint (mark_interval)) % 60;
}
if (mark_interval > 3600) {
- mark_interval -= mark_interval % 3600;
+ mark_interval -= int (rint (mark_interval)) % 3600;
}
if (mark_interval < 1) {
@@ -294,14 +317,15 @@ private:
path.AddLineToPoint (_timeline.width(), _y);
gc->StrokePath (path);
- Time t = 0;
- while ((t * _timeline.pixels_per_time_unit()) < _timeline.width()) {
+ /* Time in seconds */
+ DCPTime t;
+ while ((t.seconds() * _timeline.pixels_per_second()) < _timeline.width()) {
wxGraphicsPath path = gc->CreatePath ();
path.MoveToPoint (time_x (t), _y - 4);
path.AddLineToPoint (time_x (t), _y + 4);
gc->StrokePath (path);
- int tc = t / TIME_HZ;
+ double tc = t.seconds ();
int const h = tc / 3600;
tc -= h * 3600;
int const m = tc / 60;
@@ -315,12 +339,12 @@ private:
wxDouble str_leading;
gc->GetTextExtent (str, &str_width, &str_height, &str_descent, &str_leading);
- int const tx = _timeline.x_offset() + t * _timeline.pixels_per_time_unit();
+ int const tx = _timeline.x_offset() + t.seconds() * _timeline.pixels_per_second();
if ((tx + str_width) < _timeline.width()) {
gc->DrawText (str, time_x (t), _y + 16);
}
- t += mark_interval * TIME_HZ;
+ t += DCPTime::from_seconds (mark_interval);
}
}
@@ -335,7 +359,7 @@ Timeline::Timeline (wxWindow* parent, FilmEditor* ed, shared_ptr<Film> film)
, _film (film)
, _time_axis_view (new TimeAxisView (*this, 32))
, _tracks (0)
- , _pixels_per_time_unit (0)
+ , _pixels_per_second (0)
, _left_down (false)
, _down_view_position (0)
, _first_move (false)
@@ -401,10 +425,13 @@ Timeline::playlist_changed ()
if (dynamic_pointer_cast<AudioContent> (*i)) {
_views.push_back (shared_ptr<View> (new AudioContentView (*this, *i)));
}
+ if (dynamic_pointer_cast<SubtitleContent> (*i)) {
+ _views.push_back (shared_ptr<View> (new SubtitleContentView (*this, *i)));
+ }
}
assign_tracks ();
- setup_pixels_per_time_unit ();
+ setup_pixels_per_second ();
Refresh ();
}
@@ -416,11 +443,11 @@ Timeline::assign_tracks ()
if (!cv) {
continue;
}
-
+
shared_ptr<Content> content = cv->content();
int t = 0;
- while (1) {
+ while (true) {
ViewList::iterator j = _views.begin();
while (j != _views.end()) {
shared_ptr<ContentView> test = dynamic_pointer_cast<ContentView> (*j);
@@ -466,14 +493,14 @@ Timeline::tracks () const
}
void
-Timeline::setup_pixels_per_time_unit ()
+Timeline::setup_pixels_per_second ()
{
shared_ptr<const Film> film = _film.lock ();
- if (!film || film->length() == 0) {
+ if (!film || film->length() == DCPTime ()) {
return;
}
- _pixels_per_time_unit = static_cast<double>(width() - x_offset() * 2) / film->length ();
+ _pixels_per_second = static_cast<double>(width() - x_offset() * 2) / film->length().seconds ();
}
shared_ptr<View>
@@ -592,13 +619,13 @@ Timeline::set_position_from_event (wxMouseEvent& ev)
return;
}
- Time new_position = _down_view_position + (p.x - _down_point.x) / _pixels_per_time_unit;
+ DCPTime new_position = _down_view_position + DCPTime::from_seconds ((p.x - _down_point.x) / _pixels_per_second);
if (_snap) {
bool first = true;
- Time nearest_distance = TIME_MAX;
- Time nearest_new_position = TIME_MAX;
+ DCPTime nearest_distance = DCPTime::max ();
+ DCPTime nearest_new_position = DCPTime::max ();
/* Find the nearest content edge; this is inefficient */
for (ViewList::iterator i = _views.begin(); i != _views.end(); ++i) {
@@ -609,7 +636,7 @@ Timeline::set_position_from_event (wxMouseEvent& ev)
{
/* Snap starts to ends */
- Time const d = abs (cv->content()->end() - new_position);
+ DCPTime const d = DCPTime (cv->content()->end() - new_position).abs ();
if (first || d < nearest_distance) {
nearest_distance = d;
nearest_new_position = cv->content()->end();
@@ -618,7 +645,10 @@ Timeline::set_position_from_event (wxMouseEvent& ev)
{
/* Snap ends to starts */
- Time const d = abs (cv->content()->position() - (new_position + _down_view->content()->length_after_trim()));
+ DCPTime const d = DCPTime (
+ cv->content()->position() - (new_position + _down_view->content()->length_after_trim())
+ ).abs ();
+
if (d < nearest_distance) {
nearest_distance = d;
nearest_new_position = cv->content()->position() - _down_view->content()->length_after_trim ();
@@ -630,14 +660,14 @@ Timeline::set_position_from_event (wxMouseEvent& ev)
if (!first) {
/* Snap if it's close; `close' means within a proportion of the time on the timeline */
- if (nearest_distance < (width() / pixels_per_time_unit()) / 32) {
+ if (nearest_distance < DCPTime::from_seconds ((width() / pixels_per_second()) / 32)) {
new_position = nearest_new_position;
}
}
}
- if (new_position < 0) {
- new_position = 0;
+ if (new_position < DCPTime ()) {
+ new_position = DCPTime ();
}
_down_view->content()->set_position (new_position);
@@ -662,7 +692,7 @@ Timeline::film () const
void
Timeline::resized ()
{
- setup_pixels_per_time_unit ();
+ setup_pixels_per_second ();
}
void
diff --git a/src/wx/timeline.h b/src/wx/timeline.h
index ef1d10797..35153dd17 100644
--- a/src/wx/timeline.h
+++ b/src/wx/timeline.h
@@ -52,8 +52,8 @@ public:
return 48;
}
- double pixels_per_time_unit () const {
- return _pixels_per_time_unit;
+ double pixels_per_second () const {
+ return _pixels_per_second;
}
Position<int> tracks_position () const {
@@ -62,7 +62,7 @@ public:
int tracks () const;
- void setup_pixels_per_time_unit ();
+ void setup_pixels_per_second ();
void set_snap (bool s) {
_snap = s;
@@ -96,11 +96,11 @@ private:
ViewList _views;
boost::shared_ptr<TimeAxisView> _time_axis_view;
int _tracks;
- double _pixels_per_time_unit;
+ double _pixels_per_second;
bool _left_down;
wxPoint _down_point;
boost::shared_ptr<ContentView> _down_view;
- Time _down_view_position;
+ DCPTime _down_view_position;
bool _first_move;
ContentMenu _menu;
bool _snap;
diff --git a/src/wx/timing_panel.cc b/src/wx/timing_panel.cc
index 5cefe318a..f33e052a1 100644
--- a/src/wx/timing_panel.cc
+++ b/src/wx/timing_panel.cc
@@ -88,47 +88,43 @@ TimingPanel::film_content_changed (int property)
if (content) {
_position->set (content->position (), film_video_frame_rate);
} else {
- _position->set (0, 24);
+ _position->set (DCPTime () , 24);
}
} else if (
property == ContentProperty::LENGTH ||
property == VideoContentProperty::VIDEO_FRAME_RATE ||
- property == VideoContentProperty::VIDEO_FRAME_TYPE ||
- property == SndfileContentProperty::VIDEO_FRAME_RATE
+ property == VideoContentProperty::VIDEO_FRAME_TYPE
) {
if (content) {
_full_length->set (content->full_length (), film_video_frame_rate);
_play_length->set (content->length_after_trim (), film_video_frame_rate);
} else {
- _full_length->set (0, 24);
- _play_length->set (0, 24);
+ _full_length->set (DCPTime (), 24);
+ _play_length->set (DCPTime (), 24);
}
} else if (property == ContentProperty::TRIM_START) {
if (content) {
_trim_start->set (content->trim_start (), film_video_frame_rate);
_play_length->set (content->length_after_trim (), film_video_frame_rate);
} else {
- _trim_start->set (0, 24);
- _play_length->set (0, 24);
+ _trim_start->set (DCPTime (), 24);
+ _play_length->set (DCPTime (), 24);
}
} else if (property == ContentProperty::TRIM_END) {
if (content) {
_trim_end->set (content->trim_end (), film_video_frame_rate);
_play_length->set (content->length_after_trim (), film_video_frame_rate);
} else {
- _trim_end->set (0, 24);
- _play_length->set (0, 24);
+ _trim_end->set (DCPTime (), 24);
+ _play_length->set (DCPTime (), 24);
}
}
if (property == VideoContentProperty::VIDEO_FRAME_RATE) {
if (content) {
shared_ptr<VideoContent> vc = dynamic_pointer_cast<VideoContent> (content);
- shared_ptr<SndfileContent> sc = dynamic_pointer_cast<SndfileContent> (content);
if (vc) {
_video_frame_rate->SetValue (std_to_wx (lexical_cast<string> (vc->video_frame_rate ())));
- } else if (sc) {
- _video_frame_rate->SetValue (std_to_wx (lexical_cast<string> (sc->video_frame_rate ())));
} else {
_video_frame_rate->SetValue ("24");
}
@@ -161,7 +157,8 @@ TimingPanel::full_length_changed ()
if (c.size() == 1) {
shared_ptr<ImageContent> ic = dynamic_pointer_cast<ImageContent> (c.front ());
if (ic && ic->still ()) {
- ic->set_video_length (rint (_full_length->get (_editor->film()->video_frame_rate()) * ic->video_frame_rate() / TIME_HZ));
+ /* XXX: No effective FRC here... is this right? */
+ ic->set_video_length (ContentTime (_full_length->get (_editor->film()->video_frame_rate()), FrameRateChange (1, 1)));
}
}
}
@@ -209,10 +206,6 @@ TimingPanel::set_video_frame_rate ()
if (ic) {
ic->set_video_frame_rate (lexical_cast<float> (wx_to_std (_video_frame_rate->GetValue ())));
}
- shared_ptr<SndfileContent> sc = dynamic_pointer_cast<SndfileContent> (c.front ());
- if (sc) {
- sc->set_video_frame_rate (lexical_cast<float> (wx_to_std (_video_frame_rate->GetValue ())));
- }
_set_video_frame_rate->Enable (false);
}
}
diff --git a/src/wx/video_panel.cc b/src/wx/video_panel.cc
index ac4c29222..399e71aac 100644
--- a/src/wx/video_panel.cc
+++ b/src/wx/video_panel.cc
@@ -297,8 +297,8 @@ VideoPanel::setup_description ()
}
Crop const crop = vcs->crop ();
- if ((crop.left || crop.right || crop.top || crop.bottom) && vcs->video_size() != libdcp::Size (0, 0)) {
- libdcp::Size cropped = vcs->video_size_after_crop ();
+ if ((crop.left || crop.right || crop.top || crop.bottom) && vcs->video_size() != dcp::Size (0, 0)) {
+ dcp::Size cropped = vcs->video_size_after_crop ();
d << wxString::Format (
_("Cropped to %dx%d (%.2f:1)\n"),
cropped.width, cropped.height,
@@ -307,8 +307,8 @@ VideoPanel::setup_description ()
++lines;
}
- libdcp::Size const container_size = _editor->film()->frame_size ();
- libdcp::Size const scaled = vcs->scale().size (vcs, container_size, container_size);
+ dcp::Size const container_size = _editor->film()->frame_size ();
+ dcp::Size const scaled = vcs->scale().size (vcs, container_size, container_size);
if (scaled != vcs->video_size_after_crop ()) {
d << wxString::Format (
@@ -330,7 +330,7 @@ VideoPanel::setup_description ()
d << wxString::Format (_("Content frame rate %.4f\n"), vcs->video_frame_rate ());
++lines;
- FrameRateConversion frc (vcs->video_frame_rate(), _editor->film()->video_frame_rate ());
+ FrameRateChange frc (vcs->video_frame_rate(), _editor->film()->video_frame_rate ());
d << std_to_wx (frc.description) << "\n";
++lines;
diff --git a/src/wx/video_panel.h b/src/wx/video_panel.h
index 99633491d..4331a9712 100644
--- a/src/wx/video_panel.h
+++ b/src/wx/video_panel.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2012-2013 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2012-2014 Carl Hetherington <cth@carlh.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -17,6 +17,10 @@
*/
+/** @file src/lib/video_panel.h
+ * @brief VideoPanel class.
+ */
+
#include "lib/film.h"
#include "film_editor_panel.h"
#include "content_widget.h"
@@ -26,6 +30,9 @@ class wxStaticText;
class wxSpinCtrl;
class wxButton;
+/** @class VideoPanel
+ * @brief The video tab of the film editor.
+ */
class VideoPanel : public FilmEditorPanel
{
public:
diff --git a/src/wx/wscript b/src/wx/wscript
index a04df2d41..cd78f0649 100644
--- a/src/wx/wscript
+++ b/src/wx/wscript
@@ -38,6 +38,7 @@ sources = """
server_dialog.cc
servers_list_dialog.cc
subtitle_panel.cc
+ subtitle_view.cc
table_dialog.cc
timecode.cc
timeline.cc
diff --git a/src/wx/wx_ui_signaller.cc b/src/wx/wx_ui_signaller.cc
index f30631960..8fc6670d6 100644
--- a/src/wx/wx_ui_signaller.cc
+++ b/src/wx/wx_ui_signaller.cc
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2012 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2012-2014 Carl Hetherington <cth@carlh.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/src/wx/wx_ui_signaller.h b/src/wx/wx_ui_signaller.h
index f7df6fca4..63f2049cd 100644
--- a/src/wx/wx_ui_signaller.h
+++ b/src/wx/wx_ui_signaller.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2012 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2012-2014 Carl Hetherington <cth@carlh.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -21,6 +21,10 @@
class wxEvtHandler;
+/** @class wxUISignaller
+ * @brief UISignaller for the wxWidgets event loop
+ */
+
class wxUISignaller : public UISignaller
{
public:
diff --git a/src/wx/wx_util.cc b/src/wx/wx_util.cc
index 96278b82b..048f87908 100644
--- a/src/wx/wx_util.cc
+++ b/src/wx/wx_util.cc
@@ -123,7 +123,7 @@ int const ThreadedStaticText::_update_event_id = 10000;
* @param initial Initial text for the wxStaticText while the computation is being run.
* @param fn Function which works out what the wxStaticText content should be and returns it.
*/
-ThreadedStaticText::ThreadedStaticText (wxWindow* parent, wxString initial, function<string ()> fn)
+ThreadedStaticText::ThreadedStaticText (wxWindow* parent, wxString initial, boost::function<string ()> fn)
: wxStaticText (parent, wxID_ANY, initial)
{
Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&ThreadedStaticText::thread_finished, this, _1), _update_event_id);
@@ -139,7 +139,7 @@ ThreadedStaticText::~ThreadedStaticText ()
/** Run our thread and post the result to the GUI thread via AddPendingEvent */
void
-ThreadedStaticText::run (function<string ()> fn)
+ThreadedStaticText::run (boost::function<string ()> fn)
try
{
wxCommandEvent ev (wxEVT_COMMAND_TEXT_UPDATED, _update_event_id);