/[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 1262 - (show annotations) (download)
Sun Jul 22 15:07:08 2007 UTC (16 years, 8 months ago) by persson
File size: 9599 byte(s)
* regions can now be moved, not just resized
* improved labels in instrument properties dialog
* remove file extensions from file names when importing samples
* fixed some more checkbox layouts

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

  ViewVC Help
Powered by ViewVC