/[svn]/gigedit/trunk/src/gigedit/paramedit.cpp
ViewVC logotype

Contents of /gigedit/trunk/src/gigedit/paramedit.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1714 - (show annotations) (download)
Thu Mar 6 20:50:04 2008 UTC (16 years, 1 month ago) by persson
File size: 9689 byte(s)
* fixed compilation with gcc 4.3

1 /*
2 * Copyright (C) 2006, 2007 Andreas Persson
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2, or (at
7 * your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with program; see the file COPYING. If not, write to the Free
16 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
17 * 02110-1301 USA.
18 */
19
20 #include <cstring>
21
22 #include "paramedit.h"
23
24 namespace {
25 const char* const controlChangeTexts[] = {
26 "none", "channelaftertouch", "velocity",
27 0,
28 "modwheel", // "Modulation Wheel or Lever",
29 "breath", // "Breath Controller",
30 0,
31 "foot", // "Foot Controller",
32 "portamentotime", // "Portamento Time",
33 0, 0, 0, 0, 0, 0,
34 "effect1", // "Effect Control 1",
35 "effect2", // "Effect Control 2",
36 0, 0,
37 "genpurpose1", // "General Purpose Controller 1",
38 "genpurpose2", // "General Purpose Controller 2",
39 "genpurpose3", // "General Purpose Controller 3",
40 "genpurpose4", // "General Purpose Controller 4",
41 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
42 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
43 0, 0, 0, 0, 0, 0,
44 "sustainpedal", // "Damper Pedal on/off (Sustain)",
45 "portamento", // "Portamento On/Off",
46 "sostenuto", // "Sustenuto On/Off",
47 "softpedal", // "Soft Pedal On/Off",
48 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
49 "genpurpose5", // "General Purpose Controller 5",
50 "genpurpose6", // "General Purpose Controller 6",
51 "genpurpose7", // "General Purpose Controller 7",
52 "genpurpose8", // "General Purpose Controller 8",
53 0, 0, 0, 0, 0, 0, 0,
54 "effect1depth", // "Effects 1 Depth",
55 "effect2depth", // "Effects 2 Depth",
56 "effect3depth", // "Effects 3 Depth",
57 "effect4depth", // "Effects 4 Depth",
58 "effect5depth", // "Effects 5 Depth"
59 };
60 }
61
62 LabelWidget::LabelWidget(const char* labelText, Gtk::Widget& widget) :
63 label(Glib::ustring(labelText) + ":"),
64 widget(widget)
65 {
66 label.set_alignment(Gtk::ALIGN_LEFT);
67 }
68
69 void LabelWidget::set_sensitive(bool sensitive)
70 {
71 label.set_sensitive(sensitive);
72 widget.set_sensitive(sensitive);
73 }
74
75 NumEntry::NumEntry(const char* labelText, double lower, double upper,
76 int decimals) :
77 adjust(lower, lower, upper, 1, 10),
78 scale(adjust),
79 spinbutton(adjust),
80 LabelWidget(labelText, box)
81 {
82 spinbutton.set_digits(decimals);
83 spinbutton.set_value(0);
84 scale.set_draw_value(false);
85 box.pack_start(spinbutton, Gtk::PACK_SHRINK);
86 box.add(scale);
87 }
88
89 NumEntryGain::NumEntryGain(const char* labelText,
90 double lower, double upper,
91 int decimals, double coeff) :
92 NumEntry(labelText, lower, upper, decimals),
93 coeff(coeff),
94 value(0),
95 connected(true)
96 {
97 spinbutton.signal_value_changed().connect(
98 sigc::mem_fun(*this, &NumEntryGain::value_changed));
99 }
100
101 void NumEntryGain::value_changed()
102 {
103 if (!connected) return;
104
105 const double f = pow(10, spinbutton.get_digits());
106 int new_value = round_to_int(spinbutton.get_value() * f);
107 if (new_value != round_to_int(value / coeff * f)) {
108 value = round_to_int(new_value / f * coeff);
109 sig_changed();
110 }
111 }
112
113 void NumEntryGain::set_value(int32_t value)
114 {
115 if (value != this->value) {
116 this->value = value;
117
118 connected = false;
119 bool plus6 = value < 0;
120 spinbutton.set_value(plus6 ? 0 : value / coeff);
121 set_sensitive(!plus6);
122 connected = true;
123
124 sig_changed();
125 }
126 }
127
128
129 BoolEntryPlus6::BoolEntryPlus6(const char* labelText, NumEntryGain& eGain, int32_t plus6value) :
130 LabelWidget(labelText, checkbutton),
131 checkbutton(labelText),
132 eGain(eGain),
133 plus6value(plus6value)
134 {
135 checkbutton.signal_toggled().connect(
136 sigc::mem_fun(*this, &BoolEntryPlus6::value_changed));
137 }
138
139 void BoolEntryPlus6::value_changed()
140 {
141 if (checkbutton.get_active()) eGain.set_value(plus6value);
142 else if (eGain.get_value() < 0) eGain.set_value(0);
143 }
144
145 int32_t BoolEntryPlus6::get_value() const
146 {
147 return eGain.get_value();
148 }
149
150 void BoolEntryPlus6::set_value(int32_t value)
151 {
152 checkbutton.set_active(value < 0);
153 }
154
155 NumEntryPermille::NumEntryPermille(const char* labelText,
156 double lower, double upper, int decimals) :
157 NumEntry(labelText, lower, upper, decimals),
158 value(0)
159 {
160 spinbutton.signal_value_changed().connect(
161 sigc::mem_fun(*this, &NumEntryPermille::value_changed));
162 }
163
164 void NumEntryPermille::value_changed()
165 {
166 uint16_t new_value = uint16_t(spinbutton.get_value() * 10 + 0.5);
167 if (new_value != value) {
168 value = uint16_t(spinbutton.get_value() * 10 + 0.5);
169 sig_changed();
170 }
171 }
172
173 void NumEntryPermille::set_value(uint16_t value)
174 {
175 if (value != this->value) {
176 spinbutton.set_value(value / 10.0);
177 }
178 }
179
180
181 NoteEntry::NoteEntry(const char* labelText) :
182 NumEntryTemp<uint8_t>(labelText)
183 {
184 spinbutton.signal_input().connect(
185 sigc::mem_fun(*this, &NoteEntry::on_input));
186 spinbutton.signal_output().connect(
187 sigc::mem_fun(*this, &NoteEntry::on_output));
188 }
189
190 const char* notes[] = {
191 "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"
192 };
193
194
195 // Convert the Entry text to a number
196 int NoteEntry::on_input(double* new_value)
197 {
198 const char* str = spinbutton.get_text().c_str();
199
200 int i;
201 for (i = 11 ; i >= 0 ; i--) {
202 if (strncmp(str, notes[i], strlen(notes[i])) == 0) break;
203 }
204 if (i >= 0) {
205 char* endptr;
206 long x = strtol(str + strlen(notes[i]), &endptr, 10);
207 if (endptr != str + strlen(notes[i])) {
208 *new_value = i + (x + 1) * 12;
209 return true;
210 }
211 }
212 return Gtk::INPUT_ERROR;
213 }
214
215 // Convert the Adjustment position to text
216 bool NoteEntry::on_output()
217 {
218 int x = int(spinbutton.get_adjustment()->get_value() + 0.5);
219 char buf[10];
220 sprintf(buf, "%s%d", notes[x % 12], x / 12 - 1);
221 spinbutton.set_text(buf);
222 return true;
223 }
224
225 ChoiceEntryLeverageCtrl::ChoiceEntryLeverageCtrl(const char* labelText) :
226 align(0, 0, 0, 0),
227 LabelWidget(labelText, align)
228 {
229 for (int i = 0 ; i < 99 ; i++) {
230 if (controlChangeTexts[i]) {
231 combobox.append_text(controlChangeTexts[i]);
232 }
233 }
234 combobox.signal_changed().connect(
235 sigc::mem_fun(*this, &ChoiceEntryLeverageCtrl::value_changed));
236 align.add(combobox);
237 value.type = gig::leverage_ctrl_t::type_none;
238 value.controller_number = 0;
239 }
240
241 void ChoiceEntryLeverageCtrl::value_changed()
242 {
243 int rowno = combobox.get_active_row_number();
244 switch (rowno)
245 {
246 case -1:
247 break;
248 case 0:
249 value.type = gig::leverage_ctrl_t::type_none;
250 break;
251 case 1:
252 value.type = gig::leverage_ctrl_t::type_channelaftertouch;
253 break;
254 case 2:
255 value.type = gig::leverage_ctrl_t::type_velocity;
256 break;
257 default:
258 value.type = gig::leverage_ctrl_t::type_controlchange;
259 int x = 3;
260 for (int cc = 0 ; cc < 96 ; cc++) {
261 if (controlChangeTexts[cc + 3]) {
262 if (rowno == x) {
263 value.controller_number = cc;
264 break;
265 }
266 x++;
267 }
268 }
269 break;
270 }
271 if (rowno >= 0) sig_changed();
272 }
273
274 void ChoiceEntryLeverageCtrl::set_value(gig::leverage_ctrl_t value)
275 {
276 int x;
277 switch (value.type)
278 {
279 case gig::leverage_ctrl_t::type_none:
280 x = 0;
281 break;
282 case gig::leverage_ctrl_t::type_channelaftertouch:
283 x = 1;
284 break;
285 case gig::leverage_ctrl_t::type_velocity:
286 x = 2;
287 break;
288 case gig::leverage_ctrl_t::type_controlchange:
289 x = -1;
290 for (int cc = 0 ; cc < 96 ; cc++) {
291 if (controlChangeTexts[cc + 3]) {
292 x++;
293 if (value.controller_number == cc) {
294 x += 3;
295 break;
296 }
297 }
298 }
299 break;
300 default:
301 x = -1;
302 break;
303 }
304 combobox.set_active(x);
305 }
306
307
308 BoolEntry::BoolEntry(const char* labelText) :
309 LabelWidget(labelText, checkbutton),
310 checkbutton(labelText)
311 {
312 checkbutton.signal_toggled().connect(sig_changed.make_slot());
313 }
314
315
316 StringEntry::StringEntry(const char* labelText) :
317 LabelWidget(labelText, entry)
318 {
319 entry.signal_changed().connect(sig_changed.make_slot());
320 }
321
322 StringEntryMultiLine::StringEntryMultiLine(const char* labelText) :
323 LabelWidget(labelText, frame)
324 {
325 text_buffer = text_view.get_buffer();
326 frame.set_shadow_type(Gtk::SHADOW_IN);
327 frame.add(text_view);
328 text_buffer->signal_changed().connect(sig_changed.make_slot());
329 }
330
331 gig::String StringEntryMultiLine::get_value() const
332 {
333 Glib::ustring value = text_buffer->get_text();
334 for (int i = 0 ; (i = value.find("\x0a", i)) >= 0 ; i += 2)
335 value.replace(i, 1, "\x0d\x0a");
336 return value;
337 }
338
339 void StringEntryMultiLine::set_value(gig::String value)
340 {
341 for (int i = 0 ; (i = value.find("\x0d\x0a", i, 2)) >= 0 ; i++)
342 value.replace(i, 2, "\x0a");
343 text_buffer->set_text(value);
344 }

  ViewVC Help
Powered by ViewVC