/*
- Copyright (C) 2019 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2019-2021 Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
*/
-#include "markers_dialog.h"
-#include "wx_util.h"
-#include "timecode.h"
-#include "static_text.h"
-#include "dcpomatic_button.h"
+
#include "check_box.h"
+#include "dcpomatic_button.h"
#include "film_viewer.h"
+#include "markers.h"
+#include "markers_dialog.h"
+#include "static_text.h"
+#include "timecode.h"
+#include "wx_util.h"
#include "lib/film.h"
#include <dcp/types.h>
+#include <dcp/warnings.h>
+LIBDCP_DISABLE_WARNINGS
#include <wx/gbsizer.h>
-#include <boost/bind.hpp>
-#include <iostream>
+LIBDCP_ENABLE_WARNINGS
+#include <boost/bind/bind.hpp>
+
-using std::cout;
+using std::make_shared;
+using std::shared_ptr;
+using std::weak_ptr;
using boost::bind;
-using boost::shared_ptr;
-using boost::weak_ptr;
using boost::optional;
+using dcpomatic::DCPTime;
+
class Marker
{
public:
- Marker (wxWindow* parent, wxGridBagSizer* grid, int row, weak_ptr<Film> film_, weak_ptr<FilmViewer> viewer_, wxString name, dcp::Marker type_)
- : film (film_)
- , viewer (viewer_)
- , type (type_)
+ Marker(wxWindow* parent, wxGridBagSizer* grid, int row, weak_ptr<Film> film, FilmViewer const& viewer, wxString name, dcp::Marker type)
+ : _film(film)
+ , _viewer(viewer)
+ , _type(type)
{
- checkbox = new CheckBox(parent, name);
- grid->Add (checkbox, wxGBPosition(row, 0), wxDefaultSpan, wxALIGN_CENTER_VERTICAL);
- timecode = new Timecode<DCPTime> (parent);
- grid->Add (timecode, wxGBPosition(row, 1));
- set_button = new Button (parent, _("Set from current position"));
- grid->Add (set_button, wxGBPosition(row, 2));
-
- shared_ptr<Film> f = film.lock ();
+ _checkbox = new CheckBox(parent, name);
+ grid->Add(_checkbox, wxGBPosition(row, 0), wxDefaultSpan, wxALIGN_CENTER_VERTICAL);
+ _timecode = new Timecode<DCPTime>(parent);
+ grid->Add(_timecode, wxGBPosition(row, 1));
+ _set_button = new Button(parent, _("Set from current position"));
+ grid->Add(_set_button, wxGBPosition(row, 2));
+
+ auto f = _film.lock();
DCPOMATIC_ASSERT (f);
- optional<DCPTime> t = f->marker (type);
- checkbox->SetValue (static_cast<bool>(t));
+ auto t = f->marker(_type);
+ _checkbox->SetValue(static_cast<bool>(t));
if (t) {
- timecode->set (*t, f->video_frame_rate());
+ _timecode->set(*t, f->video_frame_rate());
}
set_sensitivity ();
- set_button->Bind (wxEVT_BUTTON, bind(&Marker::set, this));
- checkbox->Bind (wxEVT_CHECKBOX, bind(&Marker::set_sensitivity, this));
- timecode->Changed.connect (bind(&Marker::changed, this));
+ _set_button->Bind(wxEVT_BUTTON, bind(&Marker::set, this));
+ _checkbox->bind(&Marker::checkbox_clicked, this);
+ _timecode->Changed.connect(bind(&Marker::changed, this));
}
private:
+ void checkbox_clicked ()
+ {
+ set_sensitivity ();
+ changed ();
+ }
+
void set_sensitivity ()
{
- timecode->Enable (checkbox->GetValue());
- set_button->Enable (checkbox->GetValue());
+ _timecode->Enable(_checkbox->GetValue());
+ _set_button->Enable(_checkbox->GetValue());
}
void set ()
{
- shared_ptr<Film> f = film.lock ();
+ auto f = _film.lock();
DCPOMATIC_ASSERT (f);
- shared_ptr<FilmViewer> v = viewer.lock ();
- DCPOMATIC_ASSERT (v);
- timecode->set (v->position(), f->video_frame_rate());
+ _timecode->set(_viewer.position(), f->video_frame_rate());
+ changed ();
}
void changed ()
{
- shared_ptr<Film> f = film.lock ();
+ auto f = _film.lock();
DCPOMATIC_ASSERT (f);
- if (checkbox->GetValue()) {
- f->set_marker (type, timecode->get(f->video_frame_rate()));
+ auto vfr = f->video_frame_rate();
+ auto tc = _timecode->get(vfr);
+ if (tc >= f->length()) {
+ tc = f->length() - DCPTime::from_frames(1, vfr);
+ _timecode->set(tc, vfr);
+ }
+ if (_checkbox->GetValue()) {
+ f->set_marker(_type, tc);
} else {
- f->unset_marker (type);
+ f->unset_marker(_type);
}
}
- weak_ptr<Film> film;
- weak_ptr<FilmViewer> viewer;
- dcp::Marker type;
- CheckBox* checkbox;
- Timecode<DCPTime>* timecode;
- Button* set_button;
+ weak_ptr<Film> _film;
+ FilmViewer const& _viewer;
+ dcp::Marker _type;
+ CheckBox* _checkbox;
+ Timecode<dcpomatic::DCPTime>* _timecode;
+ Button* _set_button;
};
-MarkersDialog::MarkersDialog (wxWindow* parent, weak_ptr<Film> film, weak_ptr<FilmViewer> viewer)
+
+MarkersDialog::MarkersDialog(wxWindow* parent, weak_ptr<Film> film, FilmViewer const& viewer)
: wxDialog (parent, wxID_ANY, _("Markers"))
, _film (film)
{
- wxSizer* sizer = new wxBoxSizer (wxVERTICAL);
- wxGridBagSizer* grid = new wxGridBagSizer (DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
+ auto sizer = new wxBoxSizer (wxVERTICAL);
+ auto grid = new wxGridBagSizer (DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
int r = 0;
- _markers.push_back (shared_ptr<Marker>(new Marker(this, grid, r++, film, viewer, _("First frame of composition"), dcp::FFOC)));
- _markers.push_back (shared_ptr<Marker>(new Marker(this, grid, r++, film, viewer, _("Last frame of composition"), dcp::LFOC)));
- _markers.push_back (shared_ptr<Marker>(new Marker(this, grid, r++, film, viewer, _("First frame of title credits"), dcp::FFTC)));
- _markers.push_back (shared_ptr<Marker>(new Marker(this, grid, r++, film, viewer, _("Last frame of title credits"), dcp::LFTC)));
- _markers.push_back (shared_ptr<Marker>(new Marker(this, grid, r++, film, viewer, _("First frame of intermission"), dcp::FFOI)));
- _markers.push_back (shared_ptr<Marker>(new Marker(this, grid, r++, film, viewer, _("Last frame of intermission"), dcp::LFOI)));
- _markers.push_back (shared_ptr<Marker>(new Marker(this, grid, r++, film, viewer, _("First frame of end credits"), dcp::FFEC)));
- _markers.push_back (shared_ptr<Marker>(new Marker(this, grid, r++, film, viewer, _("Last frame of end credits"), dcp::LFEC)));
- _markers.push_back (shared_ptr<Marker>(new Marker(this, grid, r++, film, viewer, _("First frame of moving credits"), dcp::FFMC)));
- _markers.push_back (shared_ptr<Marker>(new Marker(this, grid, r++, film, viewer, _("Last frame of moving credits"), dcp::LFMC)));
+ for (auto const& marker: all_editable_markers()) {
+ _markers.push_back (make_shared<Marker>(this, grid, r++, film, viewer, marker.first, marker.second));
+ }
sizer->Add (grid, 0, wxALL, 8);
+
+ auto buttons = CreateSeparatedButtonSizer (wxCLOSE);
+ if (buttons) {
+ sizer->Add (buttons, wxSizerFlags().Expand().DoubleBorder());
+ }
+
SetSizerAndFit (sizer);
}