2 Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
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.
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.
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.
20 #include <boost/lexical_cast.hpp>
21 #include <wx/spinctrl.h>
22 #include <wx/gbsizer.h>
23 #include "lib/colour_conversion.h"
24 #include "lib/safe_stringstream.h"
26 #include "colour_conversion_editor.h"
30 using boost::shared_ptr;
31 using boost::lexical_cast;
33 ColourConversionEditor::ColourConversionEditor (wxWindow* parent)
34 : wxPanel (parent, wxID_ANY)
36 wxBoxSizer* overall_sizer = new wxBoxSizer (wxVERTICAL);
37 SetSizer (overall_sizer);
39 wxGridBagSizer* table = new wxGridBagSizer (DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
40 overall_sizer->Add (table, 1, wxEXPAND | wxALL, DCPOMATIC_DIALOG_BORDER);
44 add_label_to_grid_bag_sizer (table, this, _("Input gamma"), true, wxGBPosition (r, 0));
45 _input_gamma = new wxSpinCtrlDouble (this);
46 table->Add (_input_gamma, wxGBPosition (r, 1));
49 _input_gamma_linearised = new wxCheckBox (this, wxID_ANY, _("Linearise input gamma curve for low values"));
50 table->Add (_input_gamma_linearised, wxGBPosition (r, 0), wxGBSpan (1, 2));
53 wxClientDC dc (parent);
54 wxSize size = dc.GetTextExtent (wxT ("-0.12345678901"));
57 wxTextValidator validator (wxFILTER_INCLUDE_CHAR_LIST);
60 wxString n (wxT ("0123456789.-"));
61 for (size_t i = 0; i < n.Length(); ++i) {
65 validator.SetIncludes (list);
67 add_label_to_grid_bag_sizer (table, this, _("Matrix"), true, wxGBPosition (r, 0));
68 wxFlexGridSizer* matrix_sizer = new wxFlexGridSizer (3, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
69 for (int i = 0; i < 3; ++i) {
70 for (int j = 0; j < 3; ++j) {
71 _matrix[i][j] = new wxTextCtrl (this, wxID_ANY, wxT (""), wxDefaultPosition, size, 0, validator);
72 matrix_sizer->Add (_matrix[i][j]);
75 table->Add (matrix_sizer, wxGBPosition (r, 1));
78 add_label_to_grid_bag_sizer (table, this, _("Output gamma"), true, wxGBPosition (r, 0));
79 wxBoxSizer* output_sizer = new wxBoxSizer (wxHORIZONTAL);
80 /// TRANSLATORS: this means the mathematical reciprocal operation, i.e. we are dividing 1 by the control that
82 add_label_to_sizer (output_sizer, this, _("1 / "), false);
83 _output_gamma = new wxSpinCtrlDouble (this);
84 output_sizer->Add (_output_gamma);
85 table->Add (output_sizer, wxGBPosition (r, 1));
88 _input_gamma->SetRange (0.1, 4.0);
89 _input_gamma->SetDigits (2);
90 _input_gamma->SetIncrement (0.1);
91 _output_gamma->SetRange (0.1, 4.0);
92 _output_gamma->SetDigits (2);
93 _output_gamma->SetIncrement (0.1);
95 _input_gamma->Bind (wxEVT_COMMAND_SPINCTRLDOUBLE_UPDATED, boost::bind (&ColourConversionEditor::changed, this, _input_gamma));
96 _input_gamma_linearised->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&ColourConversionEditor::changed, this));
97 for (int i = 0; i < 3; ++i) {
98 for (int j = 0; j < 3; ++j) {
99 _matrix[i][j]->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&ColourConversionEditor::changed, this));
102 _output_gamma->Bind (wxEVT_COMMAND_SPINCTRLDOUBLE_UPDATED, boost::bind (&ColourConversionEditor::changed, this, _output_gamma));
106 ColourConversionEditor::set (ColourConversion conversion)
108 set_spin_ctrl (_input_gamma, conversion.input_gamma);
109 _input_gamma_linearised->SetValue (conversion.input_gamma_linearised);
110 for (int i = 0; i < 3; ++i) {
111 for (int j = 0; j < 3; ++j) {
113 s.setf (std::ios::fixed, std::ios::floatfield);
115 s << conversion.matrix (i, j);
116 _matrix[i][j]->SetValue (std_to_wx (s.str ()));
119 set_spin_ctrl (_output_gamma, conversion.output_gamma);
123 ColourConversionEditor::get () const
125 ColourConversion conversion;
127 conversion.input_gamma = _input_gamma->GetValue ();
128 conversion.input_gamma_linearised = _input_gamma_linearised->GetValue ();
130 for (int i = 0; i < 3; ++i) {
131 for (int j = 0; j < 3; ++j) {
132 string const v = wx_to_std (_matrix[i][j]->GetValue ());
134 conversion.matrix (i, j) = 0;
136 conversion.matrix (i, j) = lexical_cast<double> (v);
141 conversion.output_gamma = _output_gamma->GetValue ();
147 ColourConversionEditor::changed ()
153 ColourConversionEditor::changed (wxSpinCtrlDouble* sc)
155 /* On OS X, it seems that in some cases when a wxSpinCtrlDouble loses focus
156 it emits an erroneous changed signal, which messes things up.
159 if (fabs (_last_spin_ctrl_value[sc] - sc->GetValue()) < 1e-3) {
167 ColourConversionEditor::set_spin_ctrl (wxSpinCtrlDouble* control, double value)
169 _last_spin_ctrl_value[control] = value;
170 control->SetValue (value);