/[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 2446 - (hide annotations) (download)
Sun Apr 28 15:40:43 2013 UTC (10 years, 11 months ago) by persson
File size: 11405 byte(s)
* use character encoding Windows-1252 for all strings in gig files

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

  ViewVC Help
Powered by ViewVC