Some basics of AudioMapping.
[dcpomatic.git] / src / wx / audio_mapping_view.cc
1 /* -*- c-basic-offset: 8; default-tab-width: 8; -*- */
2
3 /*
4     Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
5
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
20 */
21
22 #include <wx/wx.h>
23 #include <wx/renderer.h>
24 #include <wx/grid.h>
25 #include <libdcp/types.h>
26 #include "lib/audio_mapping.h"
27 #include "audio_mapping_view.h"
28 #include "wx_util.h"
29
30 using std::cout;
31 using std::list;
32 using boost::shared_ptr;
33
34 /* This could go away with wxWidgets 2.9, which has an API call
35    to find these values.
36 */
37
38 #ifdef __WXMSW__
39 #define CHECKBOX_WIDTH 16
40 #define CHECKBOX_HEIGHT 16
41 #endif
42
43 #ifdef __WXGTK__
44 #define CHECKBOX_WIDTH 20
45 #define CHECKBOX_HEIGHT 20
46 #endif
47
48
49 class NoSelectionStringRenderer : public wxGridCellStringRenderer
50 {
51 public:
52         void Draw (wxGrid& grid, wxGridCellAttr& attr, wxDC& dc, const wxRect& rect, int row, int col, bool)
53         {
54                 wxGridCellStringRenderer::Draw (grid, attr, dc, rect, row, col, false);
55         }
56 };
57
58 class CheckBoxRenderer : public wxGridCellRenderer
59 {
60 public:
61
62         void Draw (wxGrid& grid, wxGridCellAttr &, wxDC& dc, const wxRect& rect, int row, int col, bool)
63         {
64 #if wxMAJOR_VERSION == 2 && wxMINOR_VERSION >= 9
65                 dc.SetPen (*wxThePenList->FindOrCreatePen (wxColour (255, 255, 255), 0, wxPENSTYLE_SOLID));
66 #else           
67                 dc.SetPen (*wxThePenList->FindOrCreatePen (wxColour (255, 255, 255), 0, wxSOLID));
68 #endif          
69                 dc.DrawRectangle (rect);
70                 
71                 wxRendererNative::Get().DrawCheckBox (
72                         &grid,
73                         dc, rect,
74                         grid.GetCellValue (row, col) == wxT("1") ? static_cast<int>(wxCONTROL_CHECKED) : 0
75                         );
76         }
77
78         wxSize GetBestSize (wxGrid &, wxGridCellAttr &, wxDC &, int, int)
79         {
80                 return wxSize (CHECKBOX_WIDTH + 4, CHECKBOX_HEIGHT + 4);
81         }
82         
83         wxGridCellRenderer* Clone () const
84         {
85                 return new CheckBoxRenderer;
86         }
87 };
88
89
90 AudioMappingView::AudioMappingView (wxWindow* parent)
91         : wxPanel (parent, wxID_ANY)
92 {
93         _grid = new wxGrid (this, wxID_ANY);
94
95         _grid->CreateGrid (0, 7);
96 #if wxMINOR_VERSION == 9
97         _grid->HideRowLabels ();
98 #else
99         _grid->SetRowLabelSize (0);
100 #endif  
101         _grid->DisableDragRowSize ();
102         _grid->DisableDragColSize ();
103         _grid->EnableEditing (false);
104         _grid->SetCellHighlightPenWidth (0);
105         _grid->SetDefaultRenderer (new NoSelectionStringRenderer);
106
107         _grid->SetColLabelValue (0, _("Content channel"));
108         _grid->SetColLabelValue (1, _("L"));
109         _grid->SetColLabelValue (2, _("R"));
110         _grid->SetColLabelValue (3, _("C"));
111         _grid->SetColLabelValue (4, _("Lfe"));
112         _grid->SetColLabelValue (5, _("Ls"));
113         _grid->SetColLabelValue (6, _("Rs"));
114
115         _grid->AutoSize ();
116
117         wxBoxSizer* s = new wxBoxSizer (wxVERTICAL);
118         s->Add (_grid, 1, wxEXPAND);
119         SetSizerAndFit (s);
120
121         Connect (wxID_ANY, wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler (AudioMappingView::left_click), 0, this);
122 }
123
124 void
125 AudioMappingView::left_click (wxGridEvent& ev)
126 {
127         if (ev.GetCol() == 0) {
128                 return;
129         }
130         
131         if (_grid->GetCellValue (ev.GetRow(), ev.GetCol()) == wxT("1")) {
132                 _grid->SetCellValue (ev.GetRow(), ev.GetCol(), wxT("0"));
133         } else {
134                 _grid->SetCellValue (ev.GetRow(), ev.GetCol(), wxT("1"));
135         }
136 }
137
138 void
139 AudioMappingView::set_mapping (AudioMapping map)
140 {
141         if (_grid->GetNumberRows ()) {
142                 _grid->DeleteRows (0, _grid->GetNumberRows ());
143         }
144
145         list<int> content_channels = map.content_channels ();
146         _grid->InsertRows (0, content_channels.size ());
147
148         for (size_t r = 0; r < content_channels.size(); ++r) {
149                 for (int c = 1; c < 7; ++c) {
150                         _grid->SetCellRenderer (r, c, new CheckBoxRenderer);
151                 }
152         }
153         
154         int n = 0;
155         for (list<int>::iterator i = content_channels.begin(); i != content_channels.end(); ++i) {
156                 _grid->SetCellValue (n, 0, wxString::Format (wxT("%d"), *i + 1));
157
158                 list<libdcp::Channel> const d = map.content_to_dcp (*i);
159                 for (list<libdcp::Channel>::const_iterator j = d.begin(); j != d.end(); ++j) {
160                         _grid->SetCellValue (n, static_cast<int> (*j) + 1, wxT("1"));
161                 }
162                 ++n;
163         }
164
165         _grid->AutoSize ();
166 }
167