add new sigc++2 directory
[ardour.git] / libs / surfaces / mackie / surface.cc
1 #include "surface.h"
2
3 #include <sstream>
4 #include <iomanip>
5 #include <iostream>
6
7 using namespace std;
8 using namespace Mackie;
9
10 Surface::Surface( uint32_t max_strips, uint32_t unit_strips )
11 : _max_strips( max_strips ), _unit_strips( unit_strips )
12 {
13 }
14
15 void Surface::init()
16 {
17         init_controls();
18         init_strips( _max_strips, _unit_strips );
19 }
20
21 Surface::~Surface()
22 {
23         // delete groups
24         for( Groups::iterator it = groups.begin(); it != groups.end(); ++it )
25         {
26                 delete it->second;
27         }
28         
29         // delete controls
30         for( Controls::iterator it = controls.begin(); it != controls.end(); ++it )
31         {
32                 delete *it;
33         }
34 }
35
36 // Mackie-specific, because of multiple devices on separate ports
37 // add the strips from 9..max_strips
38 // unit_strips is the number of strips for additional units.
39 void Surface::init_strips( uint32_t max_strips, uint32_t unit_strips )
40 {
41         if ( strips.size() < max_strips )
42         {
43                 strips.resize( max_strips );
44                 for ( uint32_t i = strips.size(); i < max_strips; ++i )
45                 {
46                         // because I can't find itoa
47                         ostringstream os;
48                         os << "strip_" << i + 1;
49                         string name = os.str();
50                         
51                         // shallow copy existing strip
52                         // which works because the controls
53                         // have the same ids across units
54                         Strip * strip = new Strip( *strips[i % unit_strips] );
55                         
56                         // update the relevant values
57                         strip->index( i );
58                         strip->name( name );
59                         
60                         // add to data structures
61                         groups[name] = strip;
62                         strips[i] = strip;
63                 }
64         }
65 }
66
67 ostream & Mackie::operator << ( ostream & os, const Mackie::Control & control )
68 {
69         os << typeid( control ).name();
70         os << " { ";
71         os << "name: " << control.name();
72         os << ", ";
73         os << "id: " << "0x" << setw(2) << setfill('0') << hex << control.id() << setfill(' ');
74         os << ", ";
75         os << "ordinal: " << dec << control.ordinal();
76         os << ", ";
77         os << "group: " << control.group().name();
78         os << " }";
79         
80         return os;
81 }
82
83 /**
84         TODO could optimise this to use enum, but it's only
85         called during the protocol class instantiation.
86
87         generated using
88
89         irb -r controls.rb
90         sf=Surface.new
91         sf.parse
92         controls = sf.groups.find{|x| x[0] =~ /strip/}.each{|x| puts x[1]}
93         controls[1].each {|x| puts "\telse if ( control.name() == \"#{x.name}\" )\n\t{\n\t\t_#{x.name} = reinterpret_cast<#{x.class.name}*>(&control);\n\t}\n"}
94 */
95 void Strip::add( Control & control )
96 {
97         Group::add( control );
98         if ( control.name() == "gain" )
99         {
100                 _gain = reinterpret_cast<Fader*>(&control);
101         }
102         else if ( control.name() == "vpot" )
103         {
104                 _vpot = reinterpret_cast<Pot*>(&control);
105         }
106         else if ( control.name() == "recenable" )
107         {
108                 _recenable = reinterpret_cast<Button*>(&control);
109         }
110         else if ( control.name() == "solo" )
111         {
112                 _solo = reinterpret_cast<Button*>(&control);
113         }
114         else if ( control.name() == "mute" )
115         {
116                 _mute = reinterpret_cast<Button*>(&control);
117         }
118         else if ( control.name() == "select" )
119         {
120                 _select = reinterpret_cast<Button*>(&control);
121         }
122         else if ( control.name() == "vselect" )
123         {
124                 _vselect = reinterpret_cast<Button*>(&control);
125         }
126         else if ( control.name() == "fader_touch" )
127         {
128                 _fader_touch = reinterpret_cast<Button*>(&control);
129         }
130         else if ( control.type() == Control::type_led || control.type() == Control::type_led_ring )
131         {
132                 // do nothing
133                 cout << "Strip::add not adding " << control << endl;
134         }
135         else
136         {
137                 ostringstream os;
138                 os << "Strip::add: unknown control type " << control;
139                 throw MackieControlException( os.str() );
140         }
141 }
142