Split test compile up into individual files.
[dcpomatic.git] / src / wx / audio_mapping_view.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 <wx/wx.h>
21 #include <wx/renderer.h>
22 #include <wx/grid.h>
23 #include <libdcp/types.h>
24 #include "lib/audio_mapping.h"
25 #include "lib/util.h"
26 #include "audio_mapping_view.h"
27 #include "wx_util.h"
28
29 using std::cout;
30 using std::list;
31 using boost::shared_ptr;
32
33 /* This could go away with wxWidgets 2.9, which has an API call
34    to find these values.
35 */
36
37 #ifdef __WXMSW__
38 #define CHECKBOX_WIDTH 16
39 #define CHECKBOX_HEIGHT 16
40 #else
41 #define CHECKBOX_WIDTH 20
42 #define CHECKBOX_HEIGHT 20
43 #endif
44
45 class NoSelectionStringRenderer : public wxGridCellStringRenderer
46 {
47 public:
48         void Draw (wxGrid& grid, wxGridCellAttr& attr, wxDC& dc, const wxRect& rect, int row, int col, bool)
49         {
50                 wxGridCellStringRenderer::Draw (grid, attr, dc, rect, row, col, false);
51         }
52 };
53
54 class CheckBoxRenderer : public wxGridCellRenderer
55 {
56 public:
57
58         void Draw (wxGrid& grid, wxGridCellAttr &, wxDC& dc, const wxRect& rect, int row, int col, bool)
59         {
60                 dc.SetPen (*wxThePenList->FindOrCreatePen (wxColour (255, 255, 255), 0, wxPENSTYLE_SOLID));
61                 dc.DrawRectangle (rect);
62                 
63                 wxRendererNative::Get().DrawCheckBox (
64                         &grid,
65                         dc, rect,
66                         grid.GetCellValue (row, col) == wxT("1") ? static_cast<int>(wxCONTROL_CHECKED) : 0
67                         );
68         }
69
70         wxSize GetBestSize (wxGrid &, wxGridCellAttr &, wxDC &, int, int)
71         {
72                 return wxSize (CHECKBOX_WIDTH + 4, CHECKBOX_HEIGHT + 4);
73         }
74         
75         wxGridCellRenderer* Clone () const
76         {
77                 return new CheckBoxRenderer;
78         }
79 };
80
81
82 AudioMappingView::AudioMappingView (wxWindow* parent)
83         : wxPanel (parent, wxID_ANY)
84 {
85         _grid = new wxGrid (this, wxID_ANY);
86
87         _grid->CreateGrid (0, 7);
88         _grid->HideRowLabels ();
89         _grid->DisableDragRowSize ();
90         _grid->DisableDragColSize ();
91         _grid->EnableEditing (false);
92         _grid->SetCellHighlightPenWidth (0);
93         _grid->SetDefaultRenderer (new NoSelectionStringRenderer);
94
95         set_column_labels ();
96
97         _sizer = new wxBoxSizer (wxVERTICAL);
98         _sizer->Add (_grid, 1, wxEXPAND | wxALL);
99         SetSizerAndFit (_sizer);
100
101         Connect (wxID_ANY, wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler (AudioMappingView::left_click), 0, this);
102 }
103
104 void
105 AudioMappingView::left_click (wxGridEvent& ev)
106 {
107         if (ev.GetCol() == 0) {
108                 return;
109         }
110         
111         if (_grid->GetCellValue (ev.GetRow(), ev.GetCol()) == wxT("1")) {
112                 cout << "set " << ev.GetRow() << " " << ev.GetCol() << " to 0.\n";
113                 _grid->SetCellValue (ev.GetRow(), ev.GetCol(), wxT("0"));
114         } else {
115                 cout << "set " << ev.GetRow() << " " << ev.GetCol() << " to 1.\n";
116                 _grid->SetCellValue (ev.GetRow(), ev.GetCol(), wxT("1"));
117         }
118
119         _map = AudioMapping (_map.content_channels ());
120         cout << "was: " << _map.dcp_to_content(libdcp::CENTRE).size() << "\n";
121         
122         for (int i = 0; i < _grid->GetNumberRows(); ++i) {
123                 for (int j = 1; j < _grid->GetNumberCols(); ++j) {
124                         if (_grid->GetCellValue (i, j) == wxT ("1")) {
125                                 _map.add (i, static_cast<libdcp::Channel> (j - 1));
126                         }
127                 }
128         }
129
130         cout << "changed: " << _map.dcp_to_content(libdcp::CENTRE).size() << "\n";
131         Changed (_map);
132 }
133
134 void
135 AudioMappingView::set (AudioMapping map)
136 {
137         _map = map;
138         
139         if (_grid->GetNumberRows ()) {
140                 _grid->DeleteRows (0, _grid->GetNumberRows ());
141         }
142
143         _grid->InsertRows (0, _map.content_channels ());
144
145         for (int r = 0; r < _map.content_channels(); ++r) {
146                 for (int c = 1; c < 7; ++c) {
147                         _grid->SetCellRenderer (r, c, new CheckBoxRenderer);
148                 }
149         }
150         
151         for (int i = 0; i < _map.content_channels(); ++i) {
152                 _grid->SetCellValue (i, 0, wxString::Format (wxT("%d"), i + 1));
153
154                 list<libdcp::Channel> const d = _map.content_to_dcp (i);
155                 for (list<libdcp::Channel>::const_iterator j = d.begin(); j != d.end(); ++j) {
156                         int const c = static_cast<int>(*j) + 1;
157                         if (c < _grid->GetNumberCols ()) {
158                                 _grid->SetCellValue (i, c, wxT("1"));
159                         }
160                 }
161         }
162 }
163
164 void
165 AudioMappingView::set_channels (int c)
166 {
167         c++;
168
169         if (c < _grid->GetNumberCols ()) {
170                 _grid->DeleteCols (c, _grid->GetNumberCols() - c);
171         } else if (c > _grid->GetNumberCols ()) {
172                 _grid->InsertCols (_grid->GetNumberCols(), c - _grid->GetNumberCols());
173                 set_column_labels ();
174         }
175
176         set (_map);
177 }
178
179 void
180 AudioMappingView::set_column_labels ()
181 {
182         int const c = _grid->GetNumberCols ();
183         
184         _grid->SetColLabelValue (0, _("Content channel"));
185         
186         if (c > 0) {
187                 _grid->SetColLabelValue (1, _("L"));
188         }
189         
190         if (c > 1) {
191                 _grid->SetColLabelValue (2, _("R"));
192         }
193         
194         if (c > 2) {
195                 _grid->SetColLabelValue (3, _("C"));
196         }
197         
198         if (c > 3) {
199                 _grid->SetColLabelValue (4, _("Lfe"));
200         }
201         
202         if (c > 4) {
203                 _grid->SetColLabelValue (5, _("Ls"));
204         }
205         
206         if (c > 5) {
207                 _grid->SetColLabelValue (6, _("Rs"));
208         }
209
210         _grid->AutoSize ();
211 }