/[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 1460 - (show annotations) (download)
Sat Oct 27 12:28:33 2007 UTC (12 years, 8 months ago) by persson
File size: 9218 byte(s)
* code refactoring: preparing for being able to edit multiple
  dimension regions simultaneously

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 spinbutton.set_value(0);
82 scale.set_draw_value(false);
83 box.pack_start(spinbutton, Gtk::PACK_SHRINK);
84 box.add(scale);
85 }
86
87 NumEntryGain::NumEntryGain(const char* labelText,
88 double lower, double upper,
89 int decimals, double coeff) :
90 NumEntry(labelText, lower, upper, decimals),
91 coeff(coeff),
92 value(0),
93 connected(true)
94 {
95 spinbutton.signal_value_changed().connect(
96 sigc::mem_fun(*this, &NumEntryGain::value_changed));
97 }
98
99 void NumEntryGain::value_changed()
100 {
101 if (!connected) return;
102
103 const double f = pow(10, spinbutton.get_digits());
104 int new_value = round_to_int(spinbutton.get_value() * f);
105 if (new_value != round_to_int(value / coeff * f)) {
106 value = round_to_int(new_value / f * coeff);
107 sig_changed();
108 }
109 }
110
111 void NumEntryGain::set_value(int32_t value)
112 {
113 if (value != this->value) {
114 this->value = value;
115
116 connected = false;
117 bool plus6 = value < 0;
118 spinbutton.set_value(plus6 ? 0 : value / coeff);
119 set_sensitive(!plus6);
120 connected = true;
121
122 sig_changed();
123 }
124 }
125
126
127 BoolEntryPlus6::BoolEntryPlus6(const char* labelText, NumEntryGain& eGain, int32_t plus6value) :
128 LabelWidget(labelText, checkbutton),
129 checkbutton(labelText),
130 eGain(eGain),
131 plus6value(plus6value)
132 {
133 checkbutton.signal_toggled().connect(
134 sigc::mem_fun(*this, &BoolEntryPlus6::value_changed));
135 }
136
137 void BoolEntryPlus6::value_changed()
138 {
139 if (checkbutton.get_active()) eGain.set_value(plus6value);
140 else if (eGain.get_value() < 0) eGain.set_value(0);
141 }
142
143 int32_t BoolEntryPlus6::get_value() const
144 {
145 return eGain.get_value();
146 }
147
148 void BoolEntryPlus6::set_value(int32_t value)
149 {
150 checkbutton.set_active(value < 0);
151 }
152
153 NumEntryPermille::NumEntryPermille(const char* labelText,
154 double lower, double upper, int decimals) :
155 NumEntry(labelText, lower, upper, decimals),
156 value(0)
157 {
158 spinbutton.signal_value_changed().connect(
159 sigc::mem_fun(*this, &NumEntryPermille::value_changed));
160 }
161
162 void NumEntryPermille::value_changed()
163 {
164 uint16_t new_value = uint16_t(spinbutton.get_value() * 10 + 0.5);
165 if (new_value != value) {
166 value = uint16_t(spinbutton.get_value() * 10 + 0.5);
167 sig_changed();
168 }
169 }
170
171 void NumEntryPermille::set_value(uint16_t value)
172 {
173 if (value != this->value) {
174 spinbutton.set_value(value / 10.0);
175 }
176 }
177
178
179 NoteEntry::NoteEntry(const char* labelText) :
180 NumEntryTemp<uint8_t>(labelText)
181 {
182 spinbutton.signal_input().connect(
183 sigc::mem_fun(*this, &NoteEntry::on_input));
184 spinbutton.signal_output().connect(
185 sigc::mem_fun(*this, &NoteEntry::on_output));
186 }
187
188 const char* notes[] = {
189 "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"
190 };
191
192
193 // Convert the Entry text to a number
194 int NoteEntry::on_input(double* new_value)
195 {
196 const char* str = spinbutton.get_text().c_str();
197
198 int i;
199 for (i = 11 ; i >= 0 ; i--) {
200 if (strncmp(str, notes[i], strlen(notes[i])) == 0) break;
201 }
202 if (i >= 0) {
203 char* endptr;
204 long x = strtol(str + strlen(notes[i]), &endptr, 10);
205 if (endptr != str + strlen(notes[i])) {
206 *new_value = i + (x + 1) * 12;
207 return true;
208 }
209 }
210 return Gtk::INPUT_ERROR;
211 }
212
213 // Convert the Adjustment position to text
214 bool NoteEntry::on_output()
215 {
216 int x = int(spinbutton.get_adjustment()->get_value() + 0.5);
217 char buf[10];
218 sprintf(buf, "%s%d", notes[x % 12], x / 12 - 1);
219 spinbutton.set_text(buf);
220 return true;
221 }
222
223 ChoiceEntryLeverageCtrl::ChoiceEntryLeverageCtrl(const char* labelText) :
224 align(0, 0, 0, 0),
225 LabelWidget(labelText, align)
226 {
227 for (int i = 0 ; i < 99 ; i++) {
228 if (controlChangeTexts[i]) {
229 combobox.append_text(controlChangeTexts[i]);
230 }
231 }
232 combobox.signal_changed().connect(
233 sigc::mem_fun(*this, &ChoiceEntryLeverageCtrl::value_changed));
234 align.add(combobox);
235 value.type = gig::leverage_ctrl_t::type_none;
236 value.controller_number = 0;
237 }
238
239 void ChoiceEntryLeverageCtrl::value_changed()
240 {
241 int rowno = combobox.get_active_row_number();
242 switch (rowno)
243 {
244 case -1:
245 break;
246 case 0:
247 value.type = gig::leverage_ctrl_t::type_none;
248 break;
249 case 1:
250 value.type = gig::leverage_ctrl_t::type_channelaftertouch;
251 break;
252 case 2:
253 value.type = gig::leverage_ctrl_t::type_velocity;
254 break;
255 default:
256 value.type = gig::leverage_ctrl_t::type_controlchange;
257 int x = 3;
258 for (int cc = 0 ; cc < 96 ; cc++) {
259 if (controlChangeTexts[cc + 3]) {
260 if (rowno == x) {
261 value.controller_number = cc;
262 break;
263 }
264 x++;
265 }
266 }
267 break;
268 }
269 if (rowno >= 0) sig_changed();
270 }
271
272 void ChoiceEntryLeverageCtrl::set_value(gig::leverage_ctrl_t value)
273 {
274 int x;
275 switch (value.type)
276 {
277 case gig::leverage_ctrl_t::type_none:
278 x = 0;
279 break;
280 case gig::leverage_ctrl_t::type_channelaftertouch:
281 x = 1;
282 break;
283 case gig::leverage_ctrl_t::type_velocity:
284 x = 2;
285 break;
286 case gig::leverage_ctrl_t::type_controlchange:
287 x = -1;
288 for (int cc = 0 ; cc < 96 ; cc++) {
289 if (controlChangeTexts[cc + 3]) {
290 x++;
291 if (value.controller_number == cc) {
292 x += 3;
293 break;
294 }
295 }
296 }
297 break;
298 default:
299 x = -1;
300 break;
301 }
302 combobox.set_active(x);
303 }
304
305
306 BoolEntry::BoolEntry(const char* labelText) :
307 LabelWidget(labelText, checkbutton),
308 checkbutton(labelText)
309 {
310 checkbutton.signal_toggled().connect(sig_changed.make_slot());
311 }
312
313
314 StringEntry::StringEntry(const char* labelText) :
315 LabelWidget(labelText, entry)
316 {
317 entry.signal_changed().connect(
318 sigc::mem_fun(*this, &StringEntry::value_changed));
319 }
320
321 void StringEntry::value_changed()
322 {
323 if (ptr) {
324 *ptr = entry.get_text();
325 sig_changed();
326 }
327 }
328
329 void StringEntry::set_ptr(gig::String* ptr)
330 {
331 this->ptr = 0;
332 entry.set_text(*ptr);
333 this->ptr = ptr;
334 }

  ViewVC Help
Powered by ViewVC