1a8008bfda4c418c95dbf3457c6480d37eb40aaf
[dcpomatic.git] / src / wx / colour_conversion_dialog.cc
1 /*
2     Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #include <boost/lexical_cast.hpp>
21 #include <wx/spinctrl.h>
22 #include <wx/gbsizer.h>
23 #include "lib/colour_conversion.h"
24 #include "wx_util.h"
25 #include "colour_conversion_dialog.h"
26
27 using std::string;
28 using std::cout;
29 using boost::shared_ptr;
30 using boost::lexical_cast;
31
32 ColourConversionDialog::ColourConversionDialog (wxWindow* parent, shared_ptr<ColourConversion> conversion)
33         : wxDialog (parent, wxID_ANY, _("Colour conversion"))
34         , _conversion (conversion)
35 {
36         wxBoxSizer* overall_sizer = new wxBoxSizer (wxVERTICAL);
37         SetSizer (overall_sizer);
38
39         wxGridBagSizer* table = new wxGridBagSizer (DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
40         overall_sizer->Add (table, 1, wxEXPAND | wxALL, DCPOMATIC_DIALOG_BORDER);
41
42         int r = 0;
43
44         add_label_to_grid_bag_sizer (table, this, _("Name"), true, wxGBPosition (r, 0));
45         _name = new wxTextCtrl (this, wxID_ANY, wxT (""));
46         table->Add (_name, wxGBPosition (r, 1), wxDefaultSpan, wxEXPAND);
47         ++r;
48
49         add_label_to_grid_bag_sizer (table, this, _("Input gamma"), true, wxGBPosition (r, 0));
50         _input_gamma = new wxSpinCtrlDouble (this);
51         table->Add (_input_gamma, wxGBPosition (r, 1));
52         ++r;
53
54         _input_gamma_linearised = new wxCheckBox (this, wxID_ANY, _("Linearise input gamma curve for low values"));
55         table->Add (_input_gamma_linearised, wxGBPosition (r, 0), wxGBSpan (1, 2));
56         ++r;
57
58         wxClientDC dc (parent);
59         wxSize size = dc.GetTextExtent (wxT ("0.123456789012"));
60         size.SetHeight (-1);
61
62         wxTextValidator validator (wxFILTER_INCLUDE_CHAR_LIST);
63         wxArrayString list;
64
65         wxString n (wxT ("0123456789.-"));
66         for (size_t i = 0; i < n.Length(); ++i) {
67                 list.Add (n[i]);
68         }
69
70         validator.SetIncludes (list);
71
72         add_label_to_grid_bag_sizer (table, this, _("Matrix"), true, wxGBPosition (r, 0));
73         wxFlexGridSizer* matrix_sizer = new wxFlexGridSizer (3, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
74         for (int x = 0; x < 3; ++x) {
75                 for (int y = 0; y < 3; ++y) {
76                         _matrix[x][y] = new wxTextCtrl (this, wxID_ANY, wxT (""), wxDefaultPosition, size, 0, validator);
77                         matrix_sizer->Add (_matrix[x][y]);
78                 }
79         }
80         table->Add (matrix_sizer, wxGBPosition (r, 1));
81         ++r;
82
83         add_label_to_grid_bag_sizer (table, this, _("Output gamma"), true, wxGBPosition (r, 0));
84         wxBoxSizer* output_sizer = new wxBoxSizer (wxHORIZONTAL);
85         /* TRANSLATORS: this means the mathematical reciprocal operation, i.e. we are dividing 1 by the control that
86            comes after it.
87         */
88         add_label_to_sizer (output_sizer, this, _("1 / "), false);
89         _output_gamma = new wxSpinCtrlDouble (this);
90         output_sizer->Add (_output_gamma);
91         table->Add (output_sizer, wxGBPosition (r, 1));
92         ++r;
93
94         wxSizer* buttons = CreateSeparatedButtonSizer (wxOK);
95         if (buttons) {
96                 overall_sizer->Add (buttons, wxSizerFlags().Expand().DoubleBorder());
97         }
98
99         SetSizer (overall_sizer);
100         overall_sizer->Layout ();
101         overall_sizer->SetSizeHints (this);
102
103         _input_gamma->SetRange(0.1, 4.0);
104         _input_gamma->SetDigits (1);
105         _input_gamma->SetIncrement (0.1);
106         _output_gamma->SetRange(0.1, 4.0);
107         _output_gamma->SetDigits (1);
108         _output_gamma->SetIncrement (0.1);
109
110         _name->SetValue (std_to_wx (conversion->name));
111         _input_gamma->SetValue (conversion->input_gamma);
112         _input_gamma_linearised->SetValue (conversion->input_gamma_linearised);
113         for (int i = 0; i < 3; ++i) {
114                 for (int j = 0; j < 3; ++j) {
115                         _matrix[i][j]->SetValue (std_to_wx (lexical_cast<string> (conversion->matrix(i, j))));
116                 }
117         }
118         _output_gamma->SetValue (conversion->output_gamma);
119
120         _name->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&ColourConversionDialog::changed, this));
121         _input_gamma->Bind (wxEVT_COMMAND_SPINCTRLDOUBLE_UPDATED, boost::bind (&ColourConversionDialog::changed, this));
122         _input_gamma_linearised->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&ColourConversionDialog::changed, this));
123         _output_gamma->Bind (wxEVT_COMMAND_SPINCTRLDOUBLE_UPDATED, boost::bind (&ColourConversionDialog::changed, this));
124         for (int i = 0; i < 3; ++i) {
125                 for (int j = 0; j < 3; ++j) {
126                         _matrix[i][j]->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&ColourConversionDialog::changed, this));
127                 }
128         }
129 }
130
131 void
132 ColourConversionDialog::changed ()
133 {
134         _conversion->name = wx_to_std (_name->GetValue ());
135         _conversion->input_gamma = _input_gamma->GetValue ();
136         _conversion->input_gamma_linearised = _input_gamma_linearised->GetValue ();
137
138         for (int i = 0; i < 3; ++i) {
139                 for (int j = 0; j < 3; ++j) {
140                         string const v = wx_to_std (_matrix[i][j]->GetValue ());
141                         if (v.empty ()) {
142                                 _conversion->matrix (i, j) = 0;
143                         } else {
144                                 _conversion->matrix (i, j) = lexical_cast<float> (v);
145                         }
146                 }
147         }
148         _conversion->output_gamma = _output_gamma->GetValue ();
149 }
150