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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1261 - (hide annotations) (download)
Thu Jul 5 17:12:20 2007 UTC (16 years, 9 months ago) by persson
File size: 9571 byte(s)
* a changed file is now marked with an asterisk in the window title
* added close confirmation dialog, shown if file is changed
* "save" means "save as" for new files
* enabled acceleration keys
* add .gig to filename in "save as" if it's not already there
* filename character encodings other than utf-8 supported

1 schoenebeck 1225 /*
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 persson 1261 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 schoenebeck 1225 }
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     eGain(eGain),
123     plus6value(plus6value)
124     {
125     checkbutton.signal_toggled().connect(
126     sigc::mem_fun(*this, &BoolEntryPlus6::value_changed));
127     }
128    
129     void BoolEntryPlus6::value_changed()
130     {
131 persson 1261 if (ptr) {
132 schoenebeck 1225 bool plus6 = checkbutton.get_active();
133     if (plus6) {
134     eGain.set_value(0);
135     *ptr = plus6value;
136 persson 1261 sig_changed();
137 schoenebeck 1225 } else {
138     if (*ptr < 0) {
139     *ptr = 0;
140 persson 1261 sig_changed();
141 schoenebeck 1225 }
142     }
143     eGain.set_sensitive(!plus6);
144     }
145     }
146    
147     void BoolEntryPlus6::set_ptr(int32_t* ptr)
148     {
149     this->ptr = 0;
150     checkbutton.set_active(*ptr < 0);
151     this->ptr = ptr;
152     }
153    
154     NumEntryPermille::NumEntryPermille(const char* labelText,
155     double lower, double upper, int decimals) :
156     NumEntry(labelText, lower, upper, decimals)
157     {
158     spinbutton.signal_value_changed().connect(
159     sigc::mem_fun(*this, &NumEntryPermille::value_changed));
160     }
161    
162     void NumEntryPermille::value_changed()
163     {
164 persson 1261 if (ptr) {
165     uint16_t new_value = uint16_t(spinbutton.get_value() * 10 + 0.5);
166     if (new_value != *ptr) {
167     *ptr = uint16_t(spinbutton.get_value() * 10 + 0.5);
168     sig_changed();
169     }
170 schoenebeck 1225 }
171     }
172    
173     void NumEntryPermille::set_ptr(uint16_t* ptr)
174     {
175     this->ptr = 0;
176     set_value(*ptr / 10.0);
177     this->ptr = ptr;
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 persson 1261 int x = int(spinbutton.get_adjustment()->get_value() + 0.5);
219 schoenebeck 1225 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     }
238    
239     void ChoiceEntryLeverageCtrl::value_changed()
240     {
241 persson 1261 if (ptr) {
242 schoenebeck 1225 int rowno = combobox.get_active_row_number();
243     switch (rowno)
244     {
245     case -1:
246     break;
247     case 0:
248     ptr->type = gig::leverage_ctrl_t::type_none;
249     break;
250     case 1:
251     ptr->type = gig::leverage_ctrl_t::type_channelaftertouch;
252     break;
253     case 2:
254     ptr->type = gig::leverage_ctrl_t::type_velocity;
255     break;
256     default:
257     ptr->type = gig::leverage_ctrl_t::type_controlchange;
258     int x = 3;
259     for (int cc = 0 ; cc < 96 ; cc++) {
260     if (controlChangeTexts[cc + 3]) {
261     if (rowno == x) {
262     ptr->controller_number = cc;
263     break;
264     }
265     x++;
266     }
267     }
268     break;
269     }
270 persson 1261 if (rowno >= 0) sig_changed();
271 schoenebeck 1225 }
272     }
273    
274     void ChoiceEntryLeverageCtrl::set_ptr(gig::leverage_ctrl_t* ptr)
275     {
276     this->ptr = 0;
277     int x;
278     switch (ptr->type)
279     {
280     case gig::leverage_ctrl_t::type_none:
281     x = 0;
282     break;
283     case gig::leverage_ctrl_t::type_channelaftertouch:
284     x = 1;
285     break;
286     case gig::leverage_ctrl_t::type_velocity:
287     x = 2;
288     break;
289     case gig::leverage_ctrl_t::type_controlchange:
290     x = -1;
291     for (int cc = 0 ; cc < 96 ; cc++) {
292     if (controlChangeTexts[cc + 3]) {
293     x++;
294     if (ptr->controller_number == cc) {
295     x += 3;
296     break;
297     }
298     }
299     }
300     break;
301     default:
302     x = -1;
303     break;
304     }
305     combobox.set_active(x);
306     this->ptr = ptr;
307     }
308    
309    
310     BoolEntry::BoolEntry(const char* labelText) :
311     LabelWidget(labelText, checkbutton),
312     checkbutton(labelText),
313     ptr(0)
314     {
315     checkbutton.signal_toggled().connect(
316     sigc::mem_fun(*this, &BoolEntry::value_changed));
317     }
318    
319     void BoolEntry::value_changed()
320     {
321 persson 1261 if (ptr) {
322 schoenebeck 1225 *ptr = checkbutton.get_active();
323 persson 1261 sig_changed();
324 schoenebeck 1225 }
325     }
326    
327     void BoolEntry::set_ptr(bool* ptr)
328     {
329     this->ptr = 0;
330     checkbutton.set_active(*ptr);
331     this->ptr = ptr;
332     }
333    
334    
335     StringEntry::StringEntry(const char* labelText) :
336     LabelWidget(labelText, entry)
337     {
338     entry.signal_changed().connect(
339     sigc::mem_fun(*this, &StringEntry::value_changed));
340     }
341    
342     void StringEntry::value_changed()
343     {
344 persson 1261 if (ptr) {
345 schoenebeck 1225 *ptr = entry.get_text();
346 persson 1261 sig_changed();
347 schoenebeck 1225 }
348     }
349    
350     void StringEntry::set_ptr(gig::String* ptr)
351     {
352     this->ptr = 0;
353     entry.set_text(*ptr);
354     this->ptr = ptr;
355     }

  ViewVC Help
Powered by ViewVC