From 2499c41097f8410cb3016e095a85d68979485a7b Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sat, 17 Aug 2013 21:47:08 +0100 Subject: [PATCH] Various bits mostly related to colour conversions. --- platform/windows/installer.nsi.32.in | 6 +- platform/windows/installer.nsi.64.in | 6 +- src/lib/colour_conversion.cc | 96 ++++++++++++-- src/lib/colour_conversion.h | 35 ++++- src/lib/config.cc | 26 ++-- src/lib/config.h | 15 ++- src/lib/dcp_video_frame.cc | 4 +- src/lib/dcp_video_frame.h | 2 +- src/lib/encoder.cc | 12 +- src/lib/encoder.h | 2 +- src/lib/server.cc | 7 +- src/lib/server.h | 7 +- src/lib/video_content.cc | 28 +++- src/lib/video_content.h | 10 ++ src/tools/dcpomatic_cli.cc | 2 +- ..._dialog.cc => colour_conversion_editor.cc} | 86 +++++++------ ...on_dialog.h => colour_conversion_editor.h} | 17 ++- src/wx/config_dialog.cc | 14 +- src/wx/config_dialog.h | 6 +- src/wx/content_colour_conversion_dialog.cc | 121 ++++++++++++++++++ src/wx/content_colour_conversion_dialog.h | 41 ++++++ src/wx/editable_list.h | 57 ++++++--- src/wx/film_editor.cc | 1 + src/wx/filter_dialog.cc | 4 +- src/wx/filter_dialog.h | 4 +- src/wx/{filter_view.cc => filter_editor.cc} | 12 +- src/wx/{filter_view.h => filter_editor.h} | 8 +- src/wx/preset_colour_conversion_dialog.cc | 68 ++++++++++ src/wx/preset_colour_conversion_dialog.h | 35 +++++ src/wx/server_dialog.cc | 33 ++--- src/wx/server_dialog.h | 9 +- src/wx/video_panel.cc | 67 ++++++---- src/wx/video_panel.h | 6 +- src/wx/wscript | 6 +- test/client_server_test.cc | 4 +- test/test.cc | 2 +- 36 files changed, 647 insertions(+), 212 deletions(-) rename src/wx/{colour_conversion_dialog.cc => colour_conversion_editor.cc} (65%) rename src/wx/{colour_conversion_dialog.h => colour_conversion_editor.h} (76%) create mode 100644 src/wx/content_colour_conversion_dialog.cc create mode 100644 src/wx/content_colour_conversion_dialog.h rename src/wx/{filter_view.cc => filter_editor.cc} (91%) rename src/wx/{filter_view.h => filter_editor.h} (88%) create mode 100644 src/wx/preset_colour_conversion_dialog.cc create mode 100644 src/wx/preset_colour_conversion_dialog.h diff --git a/platform/windows/installer.nsi.32.in b/platform/windows/installer.nsi.32.in index 30cfd806d..938024d57 100644 --- a/platform/windows/installer.nsi.32.in +++ b/platform/windows/installer.nsi.32.in @@ -48,9 +48,9 @@ File "%deps%/bin/libglib-2.0-0.dll" File "%deps%/bin/libgobject-2.0-0.dll" File "%deps%/bin/libiconv-2.dll" File "%deps%/bin/libjpeg-8.dll" -File "%deps%/bin/libMagick++-5.dll" -File "%deps%/bin/libMagickCore-5.dll" -File "%deps%/bin/libMagickWand-5.dll" +File "%deps%/bin/libMagick++-6.Q16-2.dll" +File "%deps%/bin/libMagickCore-6.Q16-1.dll" +File "%deps%/bin/libMagickWand-6.Q16-1.dll" File "%deps%/bin/libopenjpeg-1.dll" File "%deps%/bin/libpng15-15.dll" File "%deps%/bin/libsigc-2.0-0.dll" diff --git a/platform/windows/installer.nsi.64.in b/platform/windows/installer.nsi.64.in index 3cc54b4fc..941e1c047 100644 --- a/platform/windows/installer.nsi.64.in +++ b/platform/windows/installer.nsi.64.in @@ -58,9 +58,9 @@ File "%deps%/bin/libglib-2.0-0.dll" File "%deps%/bin/libgobject-2.0-0.dll" File "%deps%/bin/libiconv-2.dll" File "%deps%/bin/libjpeg-8.dll" -File "%deps%/bin/libMagick++-5.dll" -File "%deps%/bin/libMagickCore-5.dll" -File "%deps%/bin/libMagickWand-5.dll" +File "%deps%/bin/libMagick++-6.Q16-2.dll" +File "%deps%/bin/libMagickCore-6.Q16-1.dll" +File "%deps%/bin/libMagickWand-6.Q16-1.dll" File "%deps%/bin/libopenjpeg-1.dll" File "%deps%/bin/libpng15-15.dll" File "%deps%/bin/libsigc-2.0-0.dll" diff --git a/src/lib/colour_conversion.cc b/src/lib/colour_conversion.cc index 96dc0e2c9..cc25ccc67 100644 --- a/src/lib/colour_conversion.cc +++ b/src/lib/colour_conversion.cc @@ -21,18 +21,21 @@ #include #include #include +#include "config.h" #include "colour_conversion.h" #include "i18n.h" using std::list; using std::string; +using std::cout; +using std::vector; using boost::shared_ptr; using boost::lexical_cast; +using boost::optional; ColourConversion::ColourConversion () - : name (_("Untitled")) - , input_gamma (2.4) + : input_gamma (2.4) , input_gamma_linearised (true) , matrix (3, 3) , output_gamma (2.6) @@ -44,9 +47,8 @@ ColourConversion::ColourConversion () } } -ColourConversion::ColourConversion (string n, float i, bool il, float const m[3][3], float o) - : name (n) - , input_gamma (i) +ColourConversion::ColourConversion (double i, bool il, double const m[3][3], double o) + : input_gamma (i) , input_gamma_linearised (il) , matrix (3, 3) , output_gamma (o) @@ -61,8 +63,7 @@ ColourConversion::ColourConversion (string n, float i, bool il, float const m[3] ColourConversion::ColourConversion (shared_ptr node) : matrix (3, 3) { - name = node->string_child ("Name"); - input_gamma = node->number_child ("InputGamma"); + input_gamma = node->number_child ("InputGamma"); input_gamma_linearised = node->bool_child ("InputGammaLinearised"); for (int i = 0; i < 3; ++i) { @@ -75,16 +76,15 @@ ColourConversion::ColourConversion (shared_ptr node) for (list >::iterator i = m.begin(); i != m.end(); ++i) { int const ti = (*i)->number_attribute ("i"); int const tj = (*i)->number_attribute ("j"); - matrix(ti, tj) = lexical_cast ((*i)->content ()); + matrix(ti, tj) = lexical_cast ((*i)->content ()); } - output_gamma = node->number_child ("OutputGamma"); + output_gamma = node->number_child ("OutputGamma"); } void ColourConversion::as_xml (xmlpp::Node* node) const { - node->add_child("Name")->add_child_text (name); node->add_child("InputGamma")->add_child_text (lexical_cast (input_gamma)); node->add_child("InputGammaLinearised")->add_child_text (input_gamma_linearised ? "1" : "0"); @@ -99,3 +99,79 @@ ColourConversion::as_xml (xmlpp::Node* node) const node->add_child("OutputGamma")->add_child_text (lexical_cast (output_gamma)); } + +optional +ColourConversion::preset () const +{ + vector presets = Config::instance()->colour_conversions (); + size_t i = 0; + while (i < presets.size() && (presets[i].conversion != *this)) { + ++i; + } + + if (i >= presets.size ()) { + return optional (); + } + + return i; +} + +PresetColourConversion::PresetColourConversion () + : name (_("Untitled")) +{ + +} + +PresetColourConversion::PresetColourConversion (string n, double i, bool il, double const m[3][3], double o) + : name (n) + , conversion (i, il, m, o) +{ + +} + +PresetColourConversion::PresetColourConversion (shared_ptr node) + : conversion (node) +{ + name = node->string_child ("Name"); +} + +void +PresetColourConversion::as_xml (xmlpp::Node* node) const +{ + conversion.as_xml (node); + node->add_child("Name")->add_child_text (name); +} + +static bool +about_equal (double a, double b) +{ + static const double eps = 1e-6; + return fabs (a - b) < eps; +} + +bool +operator== (ColourConversion const & a, ColourConversion const & b) +{ + if ( + !about_equal (a.input_gamma, b.input_gamma) || + a.input_gamma_linearised != b.input_gamma_linearised || + !about_equal (a.output_gamma, b.output_gamma)) { + return false; + } + + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 3; ++j) { + if (!about_equal (a.matrix (i, j), b.matrix (i, j))) { + return false; + } + } + } + + return true; +} + +bool +operator!= (ColourConversion const & a, ColourConversion const & b) +{ + return !(a == b); +} diff --git a/src/lib/colour_conversion.h b/src/lib/colour_conversion.h index ed89f8c63..85d951ce1 100644 --- a/src/lib/colour_conversion.h +++ b/src/lib/colour_conversion.h @@ -17,7 +17,11 @@ */ +#ifndef DCPOMATIC_COLOUR_CONVERSION_H +#define DCPOMATIC_COLOUR_CONVERSION_H + #include +#include #include namespace cxml { @@ -28,18 +32,37 @@ namespace xmlpp { class Node; } -class ColourConversion : public boost::noncopyable +class ColourConversion { public: ColourConversion (); - ColourConversion (std::string, float, bool, float const matrix[3][3], float); + ColourConversion (double, bool, double const matrix[3][3], double); ColourConversion (boost::shared_ptr); + virtual void as_xml (xmlpp::Node *) const; + + boost::optional preset () const; + + double input_gamma; + bool input_gamma_linearised; + boost::numeric::ublas::matrix matrix; + double output_gamma; +}; + +class PresetColourConversion +{ +public: + PresetColourConversion (); + PresetColourConversion (std::string, double, bool, double const matrix[3][3], double); + PresetColourConversion (boost::shared_ptr); + void as_xml (xmlpp::Node *) const; std::string name; - float input_gamma; - bool input_gamma_linearised; - boost::numeric::ublas::matrix matrix; - float output_gamma; + ColourConversion conversion; }; + +bool operator== (ColourConversion const &, ColourConversion const &); +bool operator!= (ColourConversion const &, ColourConversion const &); + +#endif diff --git a/src/lib/config.cc b/src/lib/config.cc index 0c8413be9..10cb13ecc 100644 --- a/src/lib/config.cc +++ b/src/lib/config.cc @@ -65,13 +65,8 @@ Config::Config () _allowed_dcp_frame_rates.push_back (50); _allowed_dcp_frame_rates.push_back (60); - _colour_conversions.push_back (shared_ptr ( - new ColourConversion (_("sRGB"), 2.4, true, libdcp::colour_matrix::xyz_to_rgb, 2.6)) - ); - - _colour_conversions.push_back (shared_ptr ( - new ColourConversion (_("sRGB non-linearised"), 2.4, false, libdcp::colour_matrix::xyz_to_rgb, 2.6)) - ); + _colour_conversions.push_back (PresetColourConversion (_("sRGB"), 2.4, true, libdcp::colour_matrix::xyz_to_rgb, 2.6)); + _colour_conversions.push_back (PresetColourConversion (_("sRGB non-linearised"), 2.4, false, libdcp::colour_matrix::xyz_to_rgb, 2.6)); } void @@ -91,7 +86,7 @@ Config::read () list > servers = f.node_children ("Server"); for (list >::iterator i = servers.begin(); i != servers.end(); ++i) { - _servers.push_back (shared_ptr (new ServerDescription (*i))); + _servers.push_back (ServerDescription (*i)); } _tms_ip = f.string_child ("TMSIP"); @@ -130,7 +125,7 @@ Config::read () } for (list >::iterator i = cc.begin(); i != cc.end(); ++i) { - _colour_conversions.push_back (shared_ptr (new ColourConversion (*i))); + _colour_conversions.push_back (PresetColourConversion (*i)); } } @@ -163,7 +158,10 @@ Config::read_old_metadata () } else if (k == N_("server_port")) { _server_port = atoi (v.c_str ()); } else if (k == N_("server")) { - _servers.push_back (ServerDescription::create_from_metadata (v)); + optional server = ServerDescription::create_from_metadata (v); + if (server) { + _servers.push_back (server.get ()); + } } else if (k == N_("tms_ip")) { _tms_ip = v; } else if (k == N_("tms_path")) { @@ -237,8 +235,8 @@ Config::write () const root->add_child("DefaultDirectory")->add_child_text (_default_directory); root->add_child("ServerPort")->add_child_text (lexical_cast (_server_port)); - for (vector >::const_iterator i = _servers.begin(); i != _servers.end(); ++i) { - (*i)->as_xml (root->add_child ("Server")); + for (vector::const_iterator i = _servers.begin(); i != _servers.end(); ++i) { + i->as_xml (root->add_child ("Server")); } root->add_child("TMSIP")->add_child_text (_tms_ip); @@ -265,8 +263,8 @@ Config::write () const root->add_child("DefaultStillLength")->add_child_text (lexical_cast (_default_still_length)); root->add_child("DefaultJ2KBandwidth")->add_child_text (lexical_cast (_default_j2k_bandwidth)); - for (vector >::const_iterator i = _colour_conversions.begin(); i != _colour_conversions.end(); ++i) { - (*i)->as_xml (root->add_child ("ColourConversion")); + for (vector::const_iterator i = _colour_conversions.begin(); i != _colour_conversions.end(); ++i) { + i->as_xml (root->add_child ("ColourConversion")); } doc.write_to_file_formatted (file (false)); diff --git a/src/lib/config.h b/src/lib/config.h index 40d06a172..bce6bfd7e 100644 --- a/src/lib/config.h +++ b/src/lib/config.h @@ -29,6 +29,8 @@ #include #include #include "dci_metadata.h" +#include "colour_conversion.h" +#include "server.h" class ServerDescription; class Scaler; @@ -36,7 +38,6 @@ class Filter; class SoundProcessor; class DCPContentType; class Ratio; -class ColourConversion; /** @class Config * @brief A singleton class holding configuration. @@ -62,7 +63,7 @@ public: } /** @return J2K encoding servers to use */ - std::vector > servers () const { + std::vector servers () const { return _servers; } @@ -123,7 +124,7 @@ public: return _default_j2k_bandwidth; } - std::vector > colour_conversions () const { + std::vector colour_conversions () const { return _colour_conversions; } @@ -142,7 +143,7 @@ public: } /** @param s New list of servers */ - void set_servers (std::vector > s) { + void set_servers (std::vector s) { _servers = s; } @@ -210,7 +211,7 @@ public: _default_j2k_bandwidth = b; } - void set_colour_conversions (std::vector > const & c) { + void set_colour_conversions (std::vector const & c) { _colour_conversions = c; } @@ -233,7 +234,7 @@ private: int _server_port; /** J2K encoding servers to use */ - std::vector > _servers; + std::vector _servers; /** Scaler to use for the "A" part of A/B comparisons */ Scaler const * _reference_scaler; /** Filters to use for the "A" part of A/B comparisons */ @@ -257,7 +258,7 @@ private: DCPContentType const * _default_dcp_content_type; libdcp::XMLMetadata _dcp_metadata; int _default_j2k_bandwidth; - std::vector > _colour_conversions; + std::vector _colour_conversions; /** Singleton instance, or 0 */ static Config* _instance; diff --git a/src/lib/dcp_video_frame.cc b/src/lib/dcp_video_frame.cc index 53cf1753a..1cb20b611 100644 --- a/src/lib/dcp_video_frame.cc +++ b/src/lib/dcp_video_frame.cc @@ -213,11 +213,11 @@ DCPVideoFrame::encode_locally () * @return Encoded data. */ shared_ptr -DCPVideoFrame::encode_remotely (boost::shared_ptr serv) +DCPVideoFrame::encode_remotely (ServerDescription serv) { boost::asio::io_service io_service; boost::asio::ip::tcp::resolver resolver (io_service); - boost::asio::ip::tcp::resolver::query query (serv->host_name(), boost::lexical_cast (Config::instance()->server_port ())); + boost::asio::ip::tcp::resolver::query query (serv.host_name(), boost::lexical_cast (Config::instance()->server_port ())); boost::asio::ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve (query); shared_ptr socket (new Socket); diff --git a/src/lib/dcp_video_frame.h b/src/lib/dcp_video_frame.h index 18c8fe628..ce6444293 100644 --- a/src/lib/dcp_video_frame.h +++ b/src/lib/dcp_video_frame.h @@ -105,7 +105,7 @@ public: DCPVideoFrame (boost::shared_ptr, int, Eyes, int, int, boost::shared_ptr); boost::shared_ptr encode_locally (); - boost::shared_ptr encode_remotely (boost::shared_ptr); + boost::shared_ptr encode_remotely (ServerDescription); Eyes eyes () const { return _eyes; diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index a1c024799..29fe64e26 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -71,13 +71,13 @@ void Encoder::process_begin () { for (int i = 0; i < Config::instance()->num_local_encoding_threads (); ++i) { - _threads.push_back (new boost::thread (boost::bind (&Encoder::encoder_thread, this, shared_ptr ()))); + _threads.push_back (new boost::thread (boost::bind (&Encoder::encoder_thread, this, optional ()))); } - vector > servers = Config::instance()->servers (); + vector servers = Config::instance()->servers (); - for (vector >::iterator i = servers.begin(); i != servers.end(); ++i) { - for (int j = 0; j < (*i)->threads (); ++j) { + for (vector::iterator i = servers.begin(); i != servers.end(); ++i) { + for (int j = 0; j < i->threads (); ++j) { _threads.push_back (new boost::thread (boost::bind (&Encoder::encoder_thread, this, *i))); } } @@ -244,7 +244,7 @@ Encoder::terminate_threads () } void -Encoder::encoder_thread (shared_ptr server) +Encoder::encoder_thread (optional server) { /* Number of seconds that we currently wait between attempts to connect to the server; not relevant for localhost @@ -275,7 +275,7 @@ Encoder::encoder_thread (shared_ptr server) if (server) { try { - encoded = vf->encode_remotely (server); + encoded = vf->encode_remotely (server.get ()); if (remote_backoff > 0) { _film->log()->log (String::compose (N_("%1 was lost, but now she is found; removing backoff"), server->host_name ())); diff --git a/src/lib/encoder.h b/src/lib/encoder.h index a4df202a2..c0ea30fcb 100644 --- a/src/lib/encoder.h +++ b/src/lib/encoder.h @@ -81,7 +81,7 @@ private: void frame_done (); - void encoder_thread (boost::shared_ptr); + void encoder_thread (boost::optional); void terminate_threads (); /** Film that we are encoding */ diff --git a/src/lib/server.cc b/src/lib/server.cc index 54cffc077..de265dca4 100644 --- a/src/lib/server.cc +++ b/src/lib/server.cc @@ -49,6 +49,7 @@ using boost::algorithm::split; using boost::thread; using boost::bind; using boost::scoped_array; +using boost::optional; using libdcp::Size; ServerDescription::ServerDescription (shared_ptr node) @@ -68,17 +69,17 @@ ServerDescription::as_xml (xmlpp::Node* root) const * @param v Metadata. * @return ServerDescription, or 0. */ -shared_ptr +optional ServerDescription::create_from_metadata (string v) { vector b; split (b, v, is_any_of (N_(" "))); if (b.size() != 2) { - return shared_ptr (); + return optional (); } - return shared_ptr (new ServerDescription (b[0], atoi (b[1].c_str ()))); + return ServerDescription (b[0], atoi (b[1].c_str ())); } Server::Server (shared_ptr log) diff --git a/src/lib/server.h b/src/lib/server.h index 6307c1867..56a1fdab9 100644 --- a/src/lib/server.h +++ b/src/lib/server.h @@ -17,6 +17,9 @@ */ +#ifndef DCPOMATIC_SERVER_H +#define DCPOMATIC_SERVER_H + /** @file src/server.h * @brief Class to describe a server to which we can send * encoding work, and a class to implement such a server. @@ -78,7 +81,7 @@ public: void as_xml (xmlpp::Node *) const; - static boost::shared_ptr create_from_metadata (std::string v); + static boost::optional create_from_metadata (std::string); private: /** server's host name */ @@ -104,3 +107,5 @@ private: boost::condition _worker_condition; boost::shared_ptr _log; }; + +#endif diff --git a/src/lib/video_content.cc b/src/lib/video_content.cc index f61518ec0..8b0ec4c99 100644 --- a/src/lib/video_content.cc +++ b/src/lib/video_content.cc @@ -23,14 +23,17 @@ #include "video_examiner.h" #include "ratio.h" #include "compose.hpp" +#include "config.h" +#include "colour_conversion.h" #include "i18n.h" -int const VideoContentProperty::VIDEO_SIZE = 0; -int const VideoContentProperty::VIDEO_FRAME_RATE = 1; -int const VideoContentProperty::VIDEO_FRAME_TYPE = 2; -int const VideoContentProperty::VIDEO_CROP = 3; -int const VideoContentProperty::VIDEO_RATIO = 4; +int const VideoContentProperty::VIDEO_SIZE = 0; +int const VideoContentProperty::VIDEO_FRAME_RATE = 1; +int const VideoContentProperty::VIDEO_FRAME_TYPE = 2; +int const VideoContentProperty::VIDEO_CROP = 3; +int const VideoContentProperty::VIDEO_RATIO = 4; +int const VideoContentProperty::COLOUR_CONVERSION = 5; using std::string; using std::stringstream; @@ -46,6 +49,7 @@ VideoContent::VideoContent (shared_ptr f, Time s, VideoContent::Fram , _video_frame_rate (0) , _video_frame_type (VIDEO_FRAME_TYPE_2D) , _ratio (Ratio::from_id ("185")) + , _colour_conversion (Config::instance()->colour_conversions().front().conversion) { } @@ -56,6 +60,7 @@ VideoContent::VideoContent (shared_ptr f, boost::filesystem::path p) , _video_frame_rate (0) , _video_frame_type (VIDEO_FRAME_TYPE_2D) , _ratio (Ratio::from_id ("185")) + , _colour_conversion (Config::instance()->colour_conversions().front().conversion) { } @@ -76,6 +81,7 @@ VideoContent::VideoContent (shared_ptr f, shared_ptrnode_child ("ColourConversion")); } void @@ -94,6 +100,7 @@ VideoContent::as_xml (xmlpp::Node* node) const if (_ratio) { node->add_child("Ratio")->add_child_text (_ratio->id ()); } + _colour_conversion.as_xml (node->add_child("ColourConversion")); } void @@ -257,3 +264,14 @@ VideoContent::video_size_after_3d_split () const assert (false); } + +void +VideoContent::set_colour_conversion (ColourConversion c) +{ + { + boost::mutex::scoped_lock lm (_mutex); + _colour_conversion = c; + } + + signal_changed (VideoContentProperty::COLOUR_CONVERSION); +} diff --git a/src/lib/video_content.h b/src/lib/video_content.h index 97ef6a9fa..72c72625b 100644 --- a/src/lib/video_content.h +++ b/src/lib/video_content.h @@ -21,6 +21,7 @@ #define DCPOMATIC_VIDEO_CONTENT_H #include "content.h" +#include "colour_conversion.h" class VideoExaminer; class Ratio; @@ -33,6 +34,7 @@ public: static int const VIDEO_FRAME_TYPE; static int const VIDEO_CROP; static int const VIDEO_RATIO; + static int const COLOUR_CONVERSION; }; class VideoContent : public virtual Content @@ -71,6 +73,8 @@ public: void set_top_crop (int); void set_bottom_crop (int); + void set_colour_conversion (ColourConversion); + VideoFrameType video_frame_type () const { boost::mutex::scoped_lock lm (_mutex); return _video_frame_type; @@ -88,6 +92,11 @@ public: return _ratio; } + ColourConversion colour_conversion () const { + boost::mutex::scoped_lock lm (_mutex); + return _colour_conversion; + } + libdcp::Size video_size_after_3d_split () const; protected: @@ -106,6 +115,7 @@ private: VideoFrameType _video_frame_type; Crop _crop; Ratio const * _ratio; + ColourConversion _colour_conversion; }; #endif diff --git a/src/tools/dcpomatic_cli.cc b/src/tools/dcpomatic_cli.cc index ff7ab6ffe..7695e1e94 100644 --- a/src/tools/dcpomatic_cli.cc +++ b/src/tools/dcpomatic_cli.cc @@ -116,7 +116,7 @@ main (int argc, char* argv[]) dcpomatic_setup (); if (no_remote) { - Config::instance()->set_servers (vector > ()); + Config::instance()->set_servers (vector ()); } cout << "DCP-o-matic " << dcpomatic_version << " git " << dcpomatic_git_commit; diff --git a/src/wx/colour_conversion_dialog.cc b/src/wx/colour_conversion_editor.cc similarity index 65% rename from src/wx/colour_conversion_dialog.cc rename to src/wx/colour_conversion_editor.cc index 1a8008bfd..091028dcd 100644 --- a/src/wx/colour_conversion_dialog.cc +++ b/src/wx/colour_conversion_editor.cc @@ -22,16 +22,16 @@ #include #include "lib/colour_conversion.h" #include "wx_util.h" -#include "colour_conversion_dialog.h" +#include "colour_conversion_editor.h" using std::string; using std::cout; +using std::stringstream; using boost::shared_ptr; using boost::lexical_cast; -ColourConversionDialog::ColourConversionDialog (wxWindow* parent, shared_ptr conversion) - : wxDialog (parent, wxID_ANY, _("Colour conversion")) - , _conversion (conversion) +ColourConversionEditor::ColourConversionEditor (wxWindow* parent) + : wxPanel (parent, wxID_ANY) { wxBoxSizer* overall_sizer = new wxBoxSizer (wxVERTICAL); SetSizer (overall_sizer); @@ -41,11 +41,6 @@ ColourConversionDialog::ColourConversionDialog (wxWindow* parent, shared_ptrAdd (_name, wxGBPosition (r, 1), wxDefaultSpan, wxEXPAND); - ++r; - add_label_to_grid_bag_sizer (table, this, _("Input gamma"), true, wxGBPosition (r, 0)); _input_gamma = new wxSpinCtrlDouble (this); table->Add (_input_gamma, wxGBPosition (r, 1)); @@ -56,7 +51,7 @@ ColourConversionDialog::ColourConversionDialog (wxWindow* parent, shared_ptrAdd (_matrix[x][y]); + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 3; ++j) { + _matrix[i][j] = new wxTextCtrl (this, wxID_ANY, wxT (""), wxDefaultPosition, size, 0, validator); + matrix_sizer->Add (_matrix[i][j]); } } table->Add (matrix_sizer, wxGBPosition (r, 1)); @@ -91,15 +86,6 @@ ColourConversionDialog::ColourConversionDialog (wxWindow* parent, shared_ptrAdd (output_sizer, wxGBPosition (r, 1)); ++r; - wxSizer* buttons = CreateSeparatedButtonSizer (wxOK); - if (buttons) { - overall_sizer->Add (buttons, wxSizerFlags().Expand().DoubleBorder()); - } - - SetSizer (overall_sizer); - overall_sizer->Layout (); - overall_sizer->SetSizeHints (this); - _input_gamma->SetRange(0.1, 4.0); _input_gamma->SetDigits (1); _input_gamma->SetIncrement (0.1); @@ -107,44 +93,60 @@ ColourConversionDialog::ColourConversionDialog (wxWindow* parent, shared_ptrSetDigits (1); _output_gamma->SetIncrement (0.1); - _name->SetValue (std_to_wx (conversion->name)); - _input_gamma->SetValue (conversion->input_gamma); - _input_gamma_linearised->SetValue (conversion->input_gamma_linearised); + _input_gamma->Bind (wxEVT_COMMAND_SPINCTRLDOUBLE_UPDATED, boost::bind (&ColourConversionEditor::changed, this)); + _input_gamma_linearised->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&ColourConversionEditor::changed, this)); for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) { - _matrix[i][j]->SetValue (std_to_wx (lexical_cast (conversion->matrix(i, j)))); + _matrix[i][j]->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&ColourConversionEditor::changed, this)); } } - _output_gamma->SetValue (conversion->output_gamma); + _output_gamma->Bind (wxEVT_COMMAND_SPINCTRLDOUBLE_UPDATED, boost::bind (&ColourConversionEditor::changed, this)); +} - _name->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&ColourConversionDialog::changed, this)); - _input_gamma->Bind (wxEVT_COMMAND_SPINCTRLDOUBLE_UPDATED, boost::bind (&ColourConversionDialog::changed, this)); - _input_gamma_linearised->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&ColourConversionDialog::changed, this)); - _output_gamma->Bind (wxEVT_COMMAND_SPINCTRLDOUBLE_UPDATED, boost::bind (&ColourConversionDialog::changed, this)); +void +ColourConversionEditor::set (ColourConversion conversion) +{ + _input_gamma->SetValue (conversion.input_gamma); + _input_gamma_linearised->SetValue (conversion.input_gamma_linearised); for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) { - _matrix[i][j]->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&ColourConversionDialog::changed, this)); + stringstream s; + s.setf (std::ios::fixed, std::ios::floatfield); + s.precision (14); + s << conversion.matrix (i, j); + _matrix[i][j]->SetValue (std_to_wx (s.str ())); } } + _output_gamma->SetValue (conversion.output_gamma); } -void -ColourConversionDialog::changed () +ColourConversion +ColourConversionEditor::get () const { - _conversion->name = wx_to_std (_name->GetValue ()); - _conversion->input_gamma = _input_gamma->GetValue (); - _conversion->input_gamma_linearised = _input_gamma_linearised->GetValue (); + ColourConversion conversion; + + conversion.input_gamma = _input_gamma->GetValue (); + conversion.input_gamma_linearised = _input_gamma_linearised->GetValue (); for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) { string const v = wx_to_std (_matrix[i][j]->GetValue ()); if (v.empty ()) { - _conversion->matrix (i, j) = 0; + conversion.matrix (i, j) = 0; } else { - _conversion->matrix (i, j) = lexical_cast (v); + conversion.matrix (i, j) = lexical_cast (v); } } } - _conversion->output_gamma = _output_gamma->GetValue (); -} + conversion.output_gamma = _output_gamma->GetValue (); + + return conversion; +} + +void +ColourConversionEditor::changed () +{ + Changed (); +} + diff --git a/src/wx/colour_conversion_dialog.h b/src/wx/colour_conversion_editor.h similarity index 76% rename from src/wx/colour_conversion_dialog.h rename to src/wx/colour_conversion_editor.h index 8da6df100..8567cac22 100644 --- a/src/wx/colour_conversion_dialog.h +++ b/src/wx/colour_conversion_editor.h @@ -17,23 +17,32 @@ */ +#ifndef DCPOMATIC_COLOUR_CONVERSION_EDITOR_H +#define DCPOMATIC_COLOUR_CONVERSION_EDITOR_H + +#include #include class wxSpinCtrlDouble; class ColourConversion; -class ColourConversionDialog : public wxDialog +class ColourConversionEditor : public wxPanel { public: - ColourConversionDialog (wxWindow *, boost::shared_ptr); + ColourConversionEditor (wxWindow *); + + void set (ColourConversion); + ColourConversion get () const; + + boost::signals2::signal Changed; private: void changed (); - boost::shared_ptr _conversion; - wxTextCtrl* _name; wxSpinCtrlDouble* _input_gamma; wxCheckBox* _input_gamma_linearised; wxTextCtrl* _matrix[3][3]; wxSpinCtrlDouble* _output_gamma; }; + +#endif diff --git a/src/wx/config_dialog.cc b/src/wx/config_dialog.cc index 66f0cd186..7f1efa52f 100644 --- a/src/wx/config_dialog.cc +++ b/src/wx/config_dialog.cc @@ -40,7 +40,7 @@ #include "server_dialog.h" #include "dir_picker_ctrl.h" #include "dci_metadata_dialog.h" -#include "colour_conversion_dialog.h" +#include "preset_colour_conversion_dialog.h" using std::vector; using std::string; @@ -280,13 +280,13 @@ ConfigDialog::make_metadata_panel () } static std::string -server_column (shared_ptr s, int c) +server_column (ServerDescription s, int c) { switch (c) { case 0: - return s->host_name (); + return s.host_name (); case 1: - return lexical_cast (s->threads ()); + return lexical_cast (s.threads ()); } return ""; @@ -434,9 +434,9 @@ ConfigDialog::default_j2k_bandwidth_changed () } static std::string -colour_conversion_column (shared_ptr c) +colour_conversion_column (PresetColourConversion c) { - return c->name; + return c.name; } void @@ -444,7 +444,7 @@ ConfigDialog::make_colour_conversions_panel () { vector columns; columns.push_back (wx_to_std (_("Name"))); - _colour_conversions_panel = new EditableList ( + _colour_conversions_panel = new EditableList ( _notebook, columns, boost::bind (&Config::colour_conversions, Config::instance()), diff --git a/src/wx/config_dialog.h b/src/wx/config_dialog.h index 60d9229c4..82c4ee2a0 100644 --- a/src/wx/config_dialog.h +++ b/src/wx/config_dialog.h @@ -31,8 +31,8 @@ class DirPickerCtrl; class wxNotebook; class ServerDescription; -class ColourConversion; -class ColourConversionDialog; +class PresetColourConversion; +class PresetColourConversionDialog; class ServerDialog; /** @class ConfigDialog @@ -71,7 +71,7 @@ private: wxNotebook* _notebook; wxPanel* _misc_panel; wxPanel* _tms_panel; - EditableList* _colour_conversions_panel; + EditableList* _colour_conversions_panel; EditableList* _servers_panel; wxPanel* _metadata_panel; wxCheckBox* _set_language; diff --git a/src/wx/content_colour_conversion_dialog.cc b/src/wx/content_colour_conversion_dialog.cc new file mode 100644 index 000000000..8fca090ad --- /dev/null +++ b/src/wx/content_colour_conversion_dialog.cc @@ -0,0 +1,121 @@ +/* + Copyright (C) 2013 Carl Hetherington + + 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 +#include "lib/colour_conversion.h" +#include "lib/config.h" +#include "wx_util.h" +#include "content_colour_conversion_dialog.h" +#include "colour_conversion_editor.h" + +using std::string; +using std::vector; +using std::cout; +using boost::optional; + +ContentColourConversionDialog::ContentColourConversionDialog (wxWindow* parent) + : wxDialog (parent, wxID_ANY, _("Colour conversion")) + , _editor (new ColourConversionEditor (this)) + , _setting (false) +{ + wxBoxSizer* overall_sizer = new wxBoxSizer (wxVERTICAL); + SetSizer (overall_sizer); + + wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP); + _preset_check = new wxCheckBox (this, wxID_ANY, _("Use preset")); + table->Add (_preset_check, 0, wxALIGN_CENTER_VERTICAL); + _preset_choice = new wxChoice (this, wxID_ANY); + table->Add (_preset_choice); + + overall_sizer->Add (table, 1, wxEXPAND | wxALL, DCPOMATIC_DIALOG_BORDER); + overall_sizer->Add (new wxStaticLine (this, wxID_ANY)); + overall_sizer->Add (_editor); + + wxSizer* buttons = CreateSeparatedButtonSizer (wxOK); + if (buttons) { + overall_sizer->Add (buttons, wxSizerFlags().Expand().DoubleBorder()); + } + + overall_sizer->Layout (); + overall_sizer->SetSizeHints (this); + + _preset_check->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&ContentColourConversionDialog::preset_check_clicked, this)); + _preset_choice->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&ContentColourConversionDialog::preset_choice_changed, this)); + + _editor->Changed.connect (boost::bind (&ContentColourConversionDialog::check_for_preset, this)); + + vector presets = Config::instance()->colour_conversions (); + for (vector::const_iterator i = presets.begin(); i != presets.end(); ++i) { + _preset_choice->Append (std_to_wx (i->name)); + } +} + +ColourConversion +ContentColourConversionDialog::get () const +{ + return _editor->get (); +} + +void +ContentColourConversionDialog::set (ColourConversion c) +{ + _setting = true; + _editor->set (c); + _setting = false; + + check_for_preset (); +} + +void +ContentColourConversionDialog::check_for_preset () +{ + if (_setting) { + return; + } + + optional preset = _editor->get().preset (); + + _preset_check->SetValue (preset); + _preset_choice->Enable (preset); + _preset_choice->SetSelection (preset.get_value_or (-1)); +} + +void +ContentColourConversionDialog::preset_check_clicked () +{ + if (_preset_check->GetValue ()) { + _preset_choice->SetSelection (0); + preset_choice_changed (); + } else { + _preset_choice->SetSelection (-1); + _preset_choice->Enable (false); + } +} + +void +ContentColourConversionDialog::preset_choice_changed () +{ + vector presets = Config::instance()->colour_conversions (); + int const s = _preset_choice->GetSelection(); + if (s != -1) { + set (presets[s].conversion); + } +} + + diff --git a/src/wx/content_colour_conversion_dialog.h b/src/wx/content_colour_conversion_dialog.h new file mode 100644 index 000000000..e6069f117 --- /dev/null +++ b/src/wx/content_colour_conversion_dialog.h @@ -0,0 +1,41 @@ +/* + Copyright (C) 2013 Carl Hetherington + + 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 + +class ColourConversionEditor; + +class ContentColourConversionDialog : public wxDialog +{ +public: + ContentColourConversionDialog (wxWindow *); + + void set (ColourConversion); + ColourConversion get () const; + +private: + void check_for_preset (); + void preset_check_clicked (); + void preset_choice_changed (); + + wxCheckBox* _preset_check; + wxChoice* _preset_choice; + ColourConversionEditor* _editor; + bool _setting; +}; diff --git a/src/wx/editable_list.h b/src/wx/editable_list.h index 32cc326b6..5eb46e80d 100644 --- a/src/wx/editable_list.h +++ b/src/wx/editable_list.h @@ -26,9 +26,9 @@ public: EditableList ( wxWindow* parent, std::vector columns, - boost::function > ()> get, - boost::function >)> set, - boost::function, int)> column + boost::function ()> get, + boost::function)> set, + boost::function column ) : wxPanel (parent) , _get (get) @@ -66,8 +66,8 @@ public: table->Add (s, 0); } - std::vector > current = _get (); - for (typename std::vector >::iterator i = current.begin (); i != current.end(); ++i) { + std::vector current = _get (); + for (typename std::vector::iterator i = current.begin (); i != current.end(); ++i) { add_to_control (*i); } @@ -77,10 +77,14 @@ public: _list->Bind (wxEVT_COMMAND_LIST_ITEM_SELECTED, boost::bind (&EditableList::selection_changed, this)); _list->Bind (wxEVT_COMMAND_LIST_ITEM_DESELECTED, boost::bind (&EditableList::selection_changed, this)); + _list->Bind (wxEVT_SIZE, boost::bind (&EditableList::resized, this, _1)); selection_changed (); + } - void add_to_control (boost::shared_ptr item) +private: + + void add_to_control (T item) { wxListItem list_item; int const n = _list->GetItemCount (); @@ -101,15 +105,18 @@ public: void add_clicked () { - boost::shared_ptr new_item (new T); - S* dialog = new S (this, new_item); + T new_item; + S* dialog = new S (this); + dialog->set (new_item); dialog->ShowModal (); - dialog->Destroy (); - add_to_control (new_item); - std::vector > all = _get (); - all.push_back (new_item); + add_to_control (dialog->get ()); + + std::vector all = _get (); + all.push_back (dialog->get ()); _set (all); + + dialog->Destroy (); } void edit_clicked () @@ -119,13 +126,15 @@ public: return; } - std::vector > all = _get (); + std::vector all = _get (); assert (item >= 0 && item < int (all.size ())); - S* dialog = new S (this, all[item]); + S* dialog = new S (this); + dialog->set (all[item]); dialog->ShowModal (); + all[item] = dialog->get (); dialog->Destroy (); - + for (int i = 0; i < _columns; ++i) { _list->SetItem (item, i, std_to_wx (_column (all[item], i))); } @@ -138,16 +147,24 @@ public: _list->DeleteItem (i); } - std::vector > all = _get (); + std::vector all = _get (); all.erase (all.begin() + i); _set (all); } -private: - boost::function > ()> _get; - boost::function >)> _set; + void resized (wxSizeEvent& ev) + { + int const w = GetSize().GetWidth() / _columns; + for (int i = 0; i < _columns; ++i) { + _list->SetColumnWidth (i, w); + } + ev.Skip (); + } + + boost::function ()> _get; + boost::function )> _set; int _columns; - boost::function, int)> _column; + boost::function _column; wxButton* _add; wxButton* _edit; diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index 812da88bf..28c315a96 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -741,6 +741,7 @@ FilmEditor::content_selection_changed () film_content_changed (s, VideoContentProperty::VIDEO_CROP); film_content_changed (s, VideoContentProperty::VIDEO_RATIO); film_content_changed (s, VideoContentProperty::VIDEO_FRAME_TYPE); + film_content_changed (s, VideoContentProperty::COLOUR_CONVERSION); film_content_changed (s, AudioContentProperty::AUDIO_GAIN); film_content_changed (s, AudioContentProperty::AUDIO_DELAY); film_content_changed (s, AudioContentProperty::AUDIO_MAPPING); diff --git a/src/wx/filter_dialog.cc b/src/wx/filter_dialog.cc index 2abe53026..13907ae0c 100644 --- a/src/wx/filter_dialog.cc +++ b/src/wx/filter_dialog.cc @@ -23,14 +23,14 @@ #include "lib/film.h" #include "filter_dialog.h" -#include "filter_view.h" +#include "filter_editor.h" using namespace std; using boost::bind; FilterDialog::FilterDialog (wxWindow* parent, vector const & f) : wxDialog (parent, wxID_ANY, wxString (_("Filters"))) - , _filters (new FilterView (this, f)) + , _filters (new FilterEditor (this, f)) { wxBoxSizer* sizer = new wxBoxSizer (wxVERTICAL); sizer->Add (_filters, 1, wxEXPAND | wxALL, 6); diff --git a/src/wx/filter_dialog.h b/src/wx/filter_dialog.h index 6f8b1dd1c..d54e6f2e4 100644 --- a/src/wx/filter_dialog.h +++ b/src/wx/filter_dialog.h @@ -25,7 +25,7 @@ #include class Film; -class FilterView; +class FilterEditor; class Filter; /** @class FilterDialog @@ -41,5 +41,5 @@ public: private: void active_changed (); - FilterView* _filters; + FilterEditor* _filters; }; diff --git a/src/wx/filter_view.cc b/src/wx/filter_editor.cc similarity index 91% rename from src/wx/filter_view.cc rename to src/wx/filter_editor.cc index 757daf3fa..4dd18004b 100644 --- a/src/wx/filter_view.cc +++ b/src/wx/filter_editor.cc @@ -17,19 +17,19 @@ */ -/** @file src/filter_view.cc +/** @file src/filter_editor.cc * @brief A panel to select FFmpeg filters. */ #include #include #include "lib/filter.h" -#include "filter_view.h" +#include "filter_editor.h" #include "wx_util.h" using namespace std; -FilterView::FilterView (wxWindow* parent, vector const & active) +FilterEditor::FilterEditor (wxWindow* parent, vector const & active) : wxPanel (parent) { wxBoxSizer* sizer = new wxBoxSizer (wxVERTICAL); @@ -64,7 +64,7 @@ FilterView::FilterView (wxWindow* parent, vector const & active) bool const a = find (active.begin(), active.end(), *j) != active.end (); b->SetValue (a); _filters[*j] = b; - b->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&FilterView::filter_toggled, this)); + b->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&FilterEditor::filter_toggled, this)); sizer->Add (b); } @@ -73,13 +73,13 @@ FilterView::FilterView (wxWindow* parent, vector const & active) } void -FilterView::filter_toggled () +FilterEditor::filter_toggled () { ActiveChanged (); } vector -FilterView::active () const +FilterEditor::active () const { vector active; for (map::const_iterator i = _filters.begin(); i != _filters.end(); ++i) { diff --git a/src/wx/filter_view.h b/src/wx/filter_editor.h similarity index 88% rename from src/wx/filter_view.h rename to src/wx/filter_editor.h index 7fbef84bf..4e1d682d5 100644 --- a/src/wx/filter_view.h +++ b/src/wx/filter_editor.h @@ -17,7 +17,7 @@ */ -/** @file src/filter_view.h +/** @file src/filter_editor.h * @brief A panel to select FFmpeg filters. */ @@ -28,13 +28,13 @@ class Filter; -/** @class FilterView +/** @class FilterEditor * @brief A panel to select FFmpeg filters. */ -class FilterView : public wxPanel +class FilterEditor : public wxPanel { public: - FilterView (wxWindow *, std::vector const &); + FilterEditor (wxWindow *, std::vector const &); std::vector active () const; diff --git a/src/wx/preset_colour_conversion_dialog.cc b/src/wx/preset_colour_conversion_dialog.cc new file mode 100644 index 000000000..8c4a6dbcf --- /dev/null +++ b/src/wx/preset_colour_conversion_dialog.cc @@ -0,0 +1,68 @@ +/* + Copyright (C) 2013 Carl Hetherington + + 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 +#include "lib/colour_conversion.h" +#include "wx_util.h" +#include "preset_colour_conversion_dialog.h" +#include "colour_conversion_editor.h" + +using std::string; +using std::cout; + +PresetColourConversionDialog::PresetColourConversionDialog (wxWindow* parent) + : wxDialog (parent, wxID_ANY, _("Colour conversion")) + , _editor (new ColourConversionEditor (this)) +{ + wxBoxSizer* overall_sizer = new wxBoxSizer (wxVERTICAL); + SetSizer (overall_sizer); + + wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP); + add_label_to_sizer (table, this, _("Name"), true); + _name = new wxTextCtrl (this, wxID_ANY, wxT ("")); + table->Add (_name); + + overall_sizer->Add (table, 1, wxEXPAND | wxALL, DCPOMATIC_DIALOG_BORDER); + overall_sizer->Add (new wxStaticLine (this, wxID_ANY)); + overall_sizer->Add (_editor); + + wxSizer* buttons = CreateSeparatedButtonSizer (wxOK); + if (buttons) { + overall_sizer->Add (buttons, wxSizerFlags().Expand().DoubleBorder()); + } + + overall_sizer->Layout (); + overall_sizer->SetSizeHints (this); +} + +PresetColourConversion +PresetColourConversionDialog::get () const +{ + PresetColourConversion pc; + pc.name = wx_to_std (_name->GetValue ()); + pc.conversion = _editor->get (); + return pc; +} + +void +PresetColourConversionDialog::set (PresetColourConversion c) +{ + _name->SetValue (std_to_wx (c.name)); + _editor->set (c.conversion); +} diff --git a/src/wx/preset_colour_conversion_dialog.h b/src/wx/preset_colour_conversion_dialog.h new file mode 100644 index 000000000..4e612398c --- /dev/null +++ b/src/wx/preset_colour_conversion_dialog.h @@ -0,0 +1,35 @@ +/* + Copyright (C) 2013 Carl Hetherington + + 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 + +class ColourConversionEditor; + +class PresetColourConversionDialog : public wxDialog +{ +public: + PresetColourConversionDialog (wxWindow *); + + void set (PresetColourConversion); + PresetColourConversion get () const; + +private: + wxTextCtrl* _name; + ColourConversionEditor* _editor; +}; diff --git a/src/wx/server_dialog.cc b/src/wx/server_dialog.cc index a0f1f04ae..31b3ce5dc 100644 --- a/src/wx/server_dialog.cc +++ b/src/wx/server_dialog.cc @@ -23,15 +23,9 @@ using boost::shared_ptr; -ServerDialog::ServerDialog (wxWindow* parent, shared_ptr server) +ServerDialog::ServerDialog (wxWindow* parent) : wxDialog (parent, wxID_ANY, _("Server")) { - if (server) { - _server = server; - } else { - _server.reset (new ServerDescription (wx_to_std (N_("localhost")), 1)); - } - wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP); table->AddGrowableCol (1, 1); @@ -43,12 +37,7 @@ ServerDialog::ServerDialog (wxWindow* parent, shared_ptr serv _threads = new wxSpinCtrl (this, wxID_ANY); table->Add (_threads, 1, wxEXPAND); - _host->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&ServerDialog::host_changed, this)); _threads->SetRange (0, 256); - _threads->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&ServerDialog::threads_changed, this)); - - _host->SetValue (std_to_wx (_server->host_name ())); - _threads->SetValue (_server->threads ()); wxBoxSizer* overall_sizer = new wxBoxSizer (wxVERTICAL); overall_sizer->Add (table, 1, wxEXPAND | wxALL, 6); @@ -64,20 +53,18 @@ ServerDialog::ServerDialog (wxWindow* parent, shared_ptr serv } void -ServerDialog::host_changed () -{ - _server->set_host_name (wx_to_std (_host->GetValue ())); -} - -void -ServerDialog::threads_changed () +ServerDialog::set (ServerDescription server) { - _server->set_threads (_threads->GetValue ()); + _host->SetValue (std_to_wx (server.host_name ())); + _threads->SetValue (server.threads ()); } -shared_ptr -ServerDialog::server () const +ServerDescription +ServerDialog::get () const { - return _server; + ServerDescription server; + server.set_host_name (wx_to_std (_host->GetValue ())); + server.set_threads (_threads->GetValue ()); + return server; } diff --git a/src/wx/server_dialog.h b/src/wx/server_dialog.h index 3f1fa1f73..a6f48fe7b 100644 --- a/src/wx/server_dialog.h +++ b/src/wx/server_dialog.h @@ -25,15 +25,12 @@ class ServerDescription; class ServerDialog : public wxDialog { public: - ServerDialog (wxWindow *, boost::shared_ptr); + ServerDialog (wxWindow *); - boost::shared_ptr server () const; + void set (ServerDescription); + ServerDescription get () const; private: - void host_changed (); - void threads_changed (); - - boost::shared_ptr _server; wxTextCtrl* _host; wxSpinCtrl* _threads; }; diff --git a/src/wx/video_panel.cc b/src/wx/video_panel.cc index 5ba06b12d..bb8476d63 100644 --- a/src/wx/video_panel.cc +++ b/src/wx/video_panel.cc @@ -27,6 +27,7 @@ #include "video_panel.h" #include "wx_util.h" #include "film_editor.h" +#include "content_colour_conversion_dialog.h" using std::vector; using std::string; @@ -36,6 +37,7 @@ using std::list; using boost::shared_ptr; using boost::dynamic_pointer_cast; using boost::bind; +using boost::optional; VideoPanel::VideoPanel (FilmEditor* e) : FilmEditorPanel (e, _("Video")) @@ -78,17 +80,34 @@ VideoPanel::VideoPanel (FilmEditor* e) { add_label_to_grid_bag_sizer (grid, this, _("Filters"), true, wxGBPosition (r, 0)); wxSizer* s = new wxBoxSizer (wxHORIZONTAL); - _filters = new wxStaticText (this, wxID_ANY, _("None")); + + wxClientDC dc (this); + wxSize size = dc.GetTextExtent (wxT ("A quite long name")); + size.SetHeight (-1); + + _filters = new wxStaticText (this, wxID_ANY, _("None"), wxDefaultPosition, size); s->Add (_filters, 1, wxEXPAND | wxALIGN_CENTER_VERTICAL | wxTOP | wxBOTTOM | wxRIGHT, 6); _filters_button = new wxButton (this, wxID_ANY, _("Edit...")); s->Add (_filters_button, 0, wxALIGN_CENTER_VERTICAL); grid->Add (s, wxGBPosition (r, 1), wxDefaultSpan, wxALIGN_CENTER_VERTICAL); } ++r; + + { + add_label_to_grid_bag_sizer (grid, this, _("Colour conversion"), true, wxGBPosition (r, 0)); + wxSizer* s = new wxBoxSizer (wxHORIZONTAL); - add_label_to_grid_bag_sizer (grid, this, _("Colour conversion"), true, wxGBPosition (r, 0)); - _colour_conversion = new wxChoice (this, wxID_ANY); - grid->Add (_colour_conversion, wxGBPosition (r, 1)); + wxClientDC dc (this); + wxSize size = dc.GetTextExtent (wxT ("A quite long name")); + size.SetHeight (-1); + + _colour_conversion = new wxStaticText (this, wxID_ANY, wxT (""), wxDefaultPosition, size); + + s->Add (_colour_conversion, 1, wxEXPAND | wxALIGN_CENTER_VERTICAL | wxTOP | wxBOTTOM | wxRIGHT, 6); + _colour_conversion_button = new wxButton (this, wxID_ANY, _("Edit...")); + s->Add (_colour_conversion_button, 0, wxALIGN_CENTER_VERTICAL); + grid->Add (s, wxGBPosition (r, 1), wxDefaultSpan, wxALIGN_CENTER_VERTICAL); + } ++r; _description = new wxStaticText (this, wxID_ANY, wxT ("\n \n \n \n \n"), wxDefaultPosition, wxDefaultSize); @@ -113,16 +132,14 @@ VideoPanel::VideoPanel (FilmEditor* e) _frame_type->Append (_("2D")); _frame_type->Append (_("3D left/right")); - setup_colour_conversions (); - - _frame_type->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&VideoPanel::frame_type_changed, this)); - _left_crop->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&VideoPanel::left_crop_changed, this)); - _right_crop->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&VideoPanel::right_crop_changed, this)); - _top_crop->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&VideoPanel::top_crop_changed, this)); - _bottom_crop->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&VideoPanel::bottom_crop_changed, this)); - _ratio->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&VideoPanel::ratio_changed, this)); - _filters_button->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&VideoPanel::edit_filters_clicked, this)); - _colour_conversion->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&VideoPanel::colour_conversion_changed, this)); + _frame_type->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&VideoPanel::frame_type_changed, this)); + _left_crop->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&VideoPanel::left_crop_changed, this)); + _right_crop->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&VideoPanel::right_crop_changed, this)); + _top_crop->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&VideoPanel::top_crop_changed, this)); + _bottom_crop->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&VideoPanel::bottom_crop_changed, this)); + _ratio->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&VideoPanel::ratio_changed, this)); + _filters_button->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&VideoPanel::edit_filters_clicked, this)); + _colour_conversion_button->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&VideoPanel::edit_colour_conversion_clicked, this)); } @@ -223,6 +240,10 @@ VideoPanel::film_content_changed (shared_ptr c, int property) setup_description (); } else if (property == VideoContentProperty::VIDEO_FRAME_RATE) { setup_description (); + } else if (property == VideoContentProperty::COLOUR_CONVERSION) { + optional preset = vc ? vc->colour_conversion().preset () : optional (); + vector cc = Config::instance()->colour_conversions (); + _colour_conversion->SetLabel (preset ? std_to_wx (cc[preset.get()].name) : _("Custom")); } else if (property == FFmpegContentProperty::FILTERS) { if (fc) { pair p = Filter::ffmpeg_strings (fc->filters ()); @@ -355,16 +376,18 @@ VideoPanel::frame_type_changed () } void -VideoPanel::setup_colour_conversions () +VideoPanel::edit_colour_conversion_clicked () { - vector > cc = Config::instance()->colour_conversions (); - for (vector >::iterator i = cc.begin(); i != cc.end(); ++i) { - _colour_conversion->Append (std_to_wx ((*i)->name)); + shared_ptr vc = _editor->selected_video_content (); + if (!vc) { + return; } -} -void -VideoPanel::colour_conversion_changed () -{ + ColourConversion conversion = vc->colour_conversion (); + ContentColourConversionDialog* d = new ContentColourConversionDialog (this); + d->set (conversion); + d->ShowModal (); + vc->set_colour_conversion (d->get ()); + d->Destroy (); } diff --git a/src/wx/video_panel.h b/src/wx/video_panel.h index 62332a052..2ecf3c87f 100644 --- a/src/wx/video_panel.h +++ b/src/wx/video_panel.h @@ -41,10 +41,9 @@ private: void edit_filters_clicked (); void ratio_changed (); void frame_type_changed (); - void colour_conversion_changed (); + void edit_colour_conversion_clicked (); void setup_description (); - void setup_colour_conversions (); wxChoice* _frame_type; wxSpinCtrl* _left_crop; @@ -56,5 +55,6 @@ private: wxStaticText* _description; wxStaticText* _filters; wxButton* _filters_button; - wxChoice* _colour_conversion; + wxStaticText* _colour_conversion; + wxButton* _colour_conversion_button; }; diff --git a/src/wx/wscript b/src/wx/wscript index e0566a6ed..9c3ecdd71 100644 --- a/src/wx/wscript +++ b/src/wx/wscript @@ -9,8 +9,9 @@ sources = """ audio_mapping_view.cc audio_panel.cc audio_plot.cc - colour_conversion_dialog.cc + colour_conversion_editor.cc config_dialog.cc + content_colour_conversion_dialog.cc content_menu.cc dci_metadata_dialog.cc dir_picker_ctrl.cc @@ -18,11 +19,12 @@ sources = """ film_editor_panel.cc film_viewer.cc filter_dialog.cc - filter_view.cc + filter_editor.cc gain_calculator_dialog.cc job_manager_view.cc job_wrapper.cc new_film_dialog.cc + preset_colour_conversion_dialog.cc properties_dialog.cc repeat_dialog.cc server_dialog.cc diff --git a/test/client_server_test.cc b/test/client_server_test.cc index d695f96ce..7faf47c41 100644 --- a/test/client_server_test.cc +++ b/test/client_server_test.cc @@ -29,7 +29,7 @@ using boost::shared_ptr; using boost::thread; void -do_remote_encode (shared_ptr frame, shared_ptr description, shared_ptr locally_encoded) +do_remote_encode (shared_ptr frame, ServerDescription description, shared_ptr locally_encoded) { shared_ptr remotely_encoded; BOOST_CHECK_NO_THROW (remotely_encoded = frame->encode_remotely (description)); @@ -92,7 +92,7 @@ BOOST_AUTO_TEST_CASE (client_server_test) /* Let the server get itself ready */ dcpomatic_sleep (1); - shared_ptr description (new ServerDescription ("localhost", 2)); + ServerDescription description ("localhost", 2); list threads; for (int i = 0; i < 8; ++i) { diff --git a/test/test.cc b/test/test.cc index 21cf18c76..1c7b7e245 100644 --- a/test/test.cc +++ b/test/test.cc @@ -46,7 +46,7 @@ struct TestConfig dcpomatic_setup(); Config::instance()->set_num_local_encoding_threads (1); - Config::instance()->set_servers (vector > ()); + Config::instance()->set_servers (vector ()); Config::instance()->set_server_port (61920); Config::instance()->set_default_dci_metadata (DCIMetadata ()); Config::instance()->set_default_container (static_cast (0)); -- 2.30.2