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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1831 by persson, Tue Feb 3 19:38:19 2009 UTC revision 2538 by schoenebeck, Tue Apr 22 16:13:50 2014 UTC
# Line 1  Line 1 
1  /*  /*
2   * Copyright (C) 2006-2009 Andreas Persson   * Copyright (C) 2006-2014 Andreas Persson
3   *   *
4   * This program is free software; you can redistribute it and/or   * This program is free software; you can redistribute it and/or
5   * modify it under the terms of the GNU General Public License as   * modify it under the terms of the GNU General Public License as
# Line 22  Line 22 
22  #include "paramedit.h"  #include "paramedit.h"
23    
24  #include "global.h"  #include "global.h"
25    #include "compat.h"
26    
27    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  namespace {  namespace {
39      const char* const controlChangeTexts[] = {      const char* const controlChangeTexts[] = {
40          _("none"), _("channelaftertouch"), _("velocity"),          _("none"), _("channelaftertouch"), _("velocity"),
41          0,          0, // bank select MSB (hard coded in sampler, so discouraged to be used here, even though considerable)
42          _("modwheel"), // "Modulation Wheel or Lever",          _("modwheel"), // "Modulation Wheel or Lever",
43          _("breath"), // "Breath Controller",          _("breath"), // "Breath Controller",
44          0,          _("undefined"),
45          _("foot"), // "Foot Controller",          _("foot"), // "Foot Controller",
46          _("portamentotime"), // "Portamento Time",          _("portamentotime"), // "Portamento Time",
47          0, 0, 0, 0, 0, 0,          _("data entry MSB"),
48            _("volume"),
49            _("balance"),
50            _("undefined"),
51            _("pan"),
52            _("expression"),
53          _("effect1"), // "Effect Control 1",          _("effect1"), // "Effect Control 1",
54          _("effect2"), // "Effect Control 2",          _("effect2"), // "Effect Control 2",
55          0, 0,          _("undefined"),
56            _("undefined"),
57          _("genpurpose1"), // "General Purpose Controller 1",          _("genpurpose1"), // "General Purpose Controller 1",
58          _("genpurpose2"), // "General Purpose Controller 2",          _("genpurpose2"), // "General Purpose Controller 2",
59          _("genpurpose3"), // "General Purpose Controller 3",          _("genpurpose3"), // "General Purpose Controller 3",
60          _("genpurpose4"), // "General Purpose Controller 4",          _("genpurpose4"), // "General Purpose Controller 4",
61          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,          _("undefined"),
62            _("undefined"),
63            _("undefined"),
64            _("undefined"),
65            _("undefined"),
66            _("undefined"),
67            _("undefined"),
68            _("undefined"),
69            _("undefined"),
70            _("undefined"),
71            _("undefined"),
72            _("undefined"),
73            
74            // LSB variant of the various controllers above
75            // (so discouraged to be used here for now)
76            0, 0, 0, 0, 0, 0, 0,
77          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
78          0, 0, 0, 0, 0, 0,          0, 0, 0, 0, 0, 0,
79            
80          _("sustainpedal"), // "Damper Pedal on/off (Sustain)",          _("sustainpedal"), // "Damper Pedal on/off (Sustain)",
81          _("portamento"), // "Portamento On/Off",          _("portamento"), // "Portamento On/Off",
82          _("sostenuto"), // "Sustenuto On/Off",          _("sostenuto"), // "Sustenuto On/Off",
83          _("softpedal"), // "Soft Pedal On/Off",          _("softpedal"), // "Soft Pedal On/Off",
84          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,          _("legato"),
85            _("hold2"),
86            _("soundvariation"),
87            _("timbre"),
88            _("releasetime"),
89            _("attacktime"),
90            _("brightness"),
91            _("decaytime"),
92            _("vibratorate"),
93            _("vibratodepth"),
94            _("vibratodelay"),
95            _("undefined"),
96          _("genpurpose5"), // "General Purpose Controller 5",          _("genpurpose5"), // "General Purpose Controller 5",
97          _("genpurpose6"), // "General Purpose Controller 6",          _("genpurpose6"), // "General Purpose Controller 6",
98          _("genpurpose7"), // "General Purpose Controller 7",          _("genpurpose7"), // "General Purpose Controller 7",
99          _("genpurpose8"), // "General Purpose Controller 8",          _("genpurpose8"), // "General Purpose Controller 8",
100          0, 0, 0, 0, 0, 0, 0,          _("portamentoctrl"),
101            _("undefined"),
102            _("undefined"),
103            _("undefined"),
104            0, // high resolution velocity prefix (so discouraged to be used here)
105            _("undefined"),
106            _("undefined"),
107          _("effect1depth"), // "Effects 1 Depth",          _("effect1depth"), // "Effects 1 Depth",
108          _("effect2depth"), // "Effects 2 Depth",          _("effect2depth"), // "Effects 2 Depth",
109          _("effect3depth"), // "Effects 3 Depth",          _("effect3depth"), // "Effects 3 Depth",
110          _("effect4depth"), // "Effects 4 Depth",          _("effect4depth"), // "Effects 4 Depth",
111          _("effect5depth"), // "Effects 5 Depth"          _("effect5depth"), // "Effects 5 Depth"
112            _("dataincrement"),
113            _("datadecrement"),
114            0, // NRPN LSB (so discouraged to be used here)
115            0, // NRPN MSB (so discouraged to be used here)
116            0, // RPN LSB (so discouraged to be used here)
117            0, // RPN MSB (so discouraged to be used here)
118            _("undefined"),
119            _("undefined"),
120            _("undefined"),
121            _("undefined"),
122            _("undefined"),
123            _("undefined"),
124            _("undefined"),
125            _("undefined"),
126            _("undefined"),
127            _("undefined"),
128            _("undefined"),
129            _("undefined"),
130            _("undefined"),
131            _("undefined"),
132            _("undefined"),
133            _("undefined"),
134            _("undefined"),
135            _("undefined") // CC 119
136            // (all other ones that follow [CC 120- CC 127] are hard coded channel
137            // mode messages, so those are discouraged to be used here)
138      };      };
139  }  }
140    
141    #define controlChangeTextsSize  (sizeof(controlChangeTexts) / sizeof(char*))
142    
143  LabelWidget::LabelWidget(const char* labelText, Gtk::Widget& widget) :  LabelWidget::LabelWidget(const char* labelText, Gtk::Widget& widget) :
144      label(Glib::ustring(labelText) + ":"),      label(Glib::ustring(labelText) + ":"),
145      widget(widget)      widget(widget)
146  {  {
147      label.set_alignment(Gtk::ALIGN_LEFT);      label.set_alignment(Gtk::ALIGN_START);
148  }  }
149    
150  void LabelWidget::set_sensitive(bool sensitive)  void LabelWidget::set_sensitive(bool sensitive)
# Line 76  void LabelWidget::set_sensitive(bool sen Line 155  void LabelWidget::set_sensitive(bool sen
155    
156  NumEntry::NumEntry(const char* labelText, double lower, double upper,  NumEntry::NumEntry(const char* labelText, double lower, double upper,
157                     int decimals) :                     int decimals) :
158        LabelWidget(labelText, box),
159    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
160      adjust(lower, lower, upper, 1, 10),      adjust(lower, lower, upper, 1, 10),
161    #else
162        adjust(Gtk::Adjustment::create(lower, lower, upper, 1, 10)),
163    #endif
164      scale(adjust),      scale(adjust),
165      spinbutton(adjust),      spinbutton(adjust)
     LabelWidget(labelText, box)  
166  {  {
167        scale.set_size_request(70);
168      spinbutton.set_digits(decimals);      spinbutton.set_digits(decimals);
169      spinbutton.set_value(0);      spinbutton.set_value(0);
170        spinbutton.set_numeric();
171      scale.set_draw_value(false);      scale.set_draw_value(false);
172      box.pack_start(spinbutton, Gtk::PACK_SHRINK);      box.pack_start(spinbutton, Gtk::PACK_SHRINK);
173      box.add(scale);      box.add(scale);
# Line 92  NumEntryGain::NumEntryGain(const char* l Line 177  NumEntryGain::NumEntryGain(const char* l
177                             double lower, double upper,                             double lower, double upper,
178                             int decimals, double coeff) :                             int decimals, double coeff) :
179      NumEntry(labelText, lower, upper, decimals),      NumEntry(labelText, lower, upper, decimals),
     coeff(coeff),  
180      value(0),      value(0),
181        coeff(coeff),
182      connected(true)      connected(true)
183  {  {
184      spinbutton.signal_value_changed().connect(      spinbutton.signal_value_changed().connect(
# Line 183  void NumEntryPermille::set_value(uint16_ Line 268  void NumEntryPermille::set_value(uint16_
268  NoteEntry::NoteEntry(const char* labelText) :  NoteEntry::NoteEntry(const char* labelText) :
269      NumEntryTemp<uint8_t>(labelText)      NumEntryTemp<uint8_t>(labelText)
270  {  {
271      spinbutton.signal_input().connect(      spin_button_show_notes(spinbutton);
         sigc::mem_fun(*this, &NoteEntry::on_input));  
     spinbutton.signal_output().connect(  
         sigc::mem_fun(*this, &NoteEntry::on_output));  
272  }  }
273    
274  const char* notes[] = {  namespace {
275      _("C"), _("C#"), _("D"), _("D#"), _("E"), _("F"),_("F#"),      const char* notes[] = {
276      _("G"), _("G#"), _("A"), _("A#"), _("B")          _("C"), _("C#"), _("D"), _("D#"), _("E"), _("F"),_("F#"),
277  };          _("G"), _("G#"), _("A"), _("A#"), _("B")
278        };
279    
280        int note_value(const Glib::ustring& note, double* value)
281        {
282            const char* str = note.c_str();
283    
284            int i;
285            for (i = 11 ; i >= 0 ; i--) {
286                if (strncasecmp(str, notes[i], strlen(notes[i])) == 0) break;
287            }
288            if (i >= 0) {
289                char* endptr;
290                long x = strtol(str + strlen(notes[i]), &endptr, 10);
291                if (endptr != str + strlen(notes[i])) {
292                    *value = std::max(0L, std::min(i + (x + 1) * 12, 127L));
293                    return true;
294                }
295            } else {
296                char* endptr;
297                long x = strtol(str, &endptr, 10);
298                if (endptr != str) {
299                    *value = std::max(0L, std::min(x, 127L));
300                    return true;
301                }
302            }
303            return Gtk::INPUT_ERROR;
304        }
305    }
306    
307  // Convert the Entry text to a number  int note_value(const Glib::ustring& note)
 int NoteEntry::on_input(double* new_value)  
308  {  {
309      const char* str = spinbutton.get_text().c_str();      double value = 0;
310        note_value(note, &value);
311        return value;
312    }
313    
314      int i;  Glib::ustring note_str(int note)
315      for (i = 11 ; i >= 0 ; i--) {  {
316          if (strncmp(str, notes[i], strlen(notes[i])) == 0) break;      char buf[10];
317        sprintf(buf, "%s%d", notes[note % 12], note / 12 - 1);
318        return buf;
319    }
320    
321    namespace {
322        // Convert the Entry text to a number
323        int on_input(double* new_value, Gtk::SpinButton* spinbutton) {
324            return note_value(spinbutton->get_text(), new_value);
325      }      }
326      if (i >= 0) {  
327          char* endptr;      // Convert the Adjustment position to text
328          long x = strtol(str + strlen(notes[i]), &endptr, 10);      bool on_output(Gtk::SpinButton* spinbutton) {
329          if (endptr != str + strlen(notes[i])) {          spinbutton->set_text(
330              *new_value = i + (x + 1) * 12;              note_str(spinbutton->get_adjustment()->get_value() + 0.5));
331              return true;          return true;
         }  
332      }      }
     return Gtk::INPUT_ERROR;  
333  }  }
334    
335  // Convert the Adjustment position to text  // Make a SpinButton show notes instead of numbers
336  bool NoteEntry::on_output()  void spin_button_show_notes(Gtk::SpinButton& spin_button)
337  {  {
338      int x = int(spinbutton.get_adjustment()->get_value() + 0.5);      spin_button.set_numeric(false);
339      char buf[10];      spin_button.set_width_chars(4);
340      sprintf(buf, "%s%d", notes[x % 12], x / 12 - 1);      spin_button.signal_input().connect(
341      spinbutton.set_text(buf);          sigc::bind(sigc::ptr_fun(&on_input), &spin_button));
342      return true;      spin_button.signal_output().connect(
343            sigc::bind(sigc::ptr_fun(&on_output), &spin_button));
344  }  }
345    
346  ChoiceEntryLeverageCtrl::ChoiceEntryLeverageCtrl(const char* labelText) :  ChoiceEntryLeverageCtrl::ChoiceEntryLeverageCtrl(const char* labelText) :
347      align(0, 0, 0, 0),      LabelWidget(labelText, align),
348      LabelWidget(labelText, align)      align(0, 0, 0, 0)
349  {  {
350      for (int i = 0 ; i < 99 ; i++) {      for (int i = 0 ; i < controlChangeTextsSize ; i++) {
351          if (controlChangeTexts[i]) {          if (controlChangeTexts[i]) {
352              combobox.append_text(controlChangeTexts[i]);              const int cc = i - 3;
353                Glib::ustring s = (i < 3)
354                    ? controlChangeTexts[i]
355                    : Glib::ustring::compose("CC%1: %2", cc, controlChangeTexts[i]);
356    #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 24) || GTKMM_MAJOR_VERSION < 2
357                combobox.append_text(s);
358    #else
359                combobox.append(s);
360    #endif
361          }          }
362      }      }
363      combobox.signal_changed().connect(      combobox.signal_changed().connect(
# Line 260  void ChoiceEntryLeverageCtrl::value_chan Line 386  void ChoiceEntryLeverageCtrl::value_chan
386      default:      default:
387          value.type = gig::leverage_ctrl_t::type_controlchange;          value.type = gig::leverage_ctrl_t::type_controlchange;
388          int x = 3;          int x = 3;
389          for (int cc = 0 ; cc < 96 ; cc++) {          for (uint cc = 0 ; cc < controlChangeTextsSize - 3 ; cc++) {
390              if (controlChangeTexts[cc + 3]) {              if (controlChangeTexts[cc + 3]) {
391                  if (rowno == x) {                  if (rowno == x) {
392                      value.controller_number = cc;                      value.controller_number = cc;
# Line 276  void ChoiceEntryLeverageCtrl::value_chan Line 402  void ChoiceEntryLeverageCtrl::value_chan
402    
403  void ChoiceEntryLeverageCtrl::set_value(gig::leverage_ctrl_t value)  void ChoiceEntryLeverageCtrl::set_value(gig::leverage_ctrl_t value)
404  {  {
405      int x;      int comboIndex;
406      switch (value.type)      switch (value.type)
407      {      {
408      case gig::leverage_ctrl_t::type_none:      case gig::leverage_ctrl_t::type_none:
409          x = 0;          comboIndex = 0;
410          break;          break;
411      case gig::leverage_ctrl_t::type_channelaftertouch:      case gig::leverage_ctrl_t::type_channelaftertouch:
412          x = 1;          comboIndex = 1;
413          break;          break;
414      case gig::leverage_ctrl_t::type_velocity:      case gig::leverage_ctrl_t::type_velocity:
415          x = 2;          comboIndex = 2;
416          break;          break;
417      case gig::leverage_ctrl_t::type_controlchange:      case gig::leverage_ctrl_t::type_controlchange: {
418          x = -1;          comboIndex = -1;
419          for (int cc = 0 ; cc < 96 ; cc++) {          int x = 3;
420            for (uint cc = 0 ; cc < controlChangeTextsSize - 3 ; cc++) {
421              if (controlChangeTexts[cc + 3]) {              if (controlChangeTexts[cc + 3]) {
                 x++;  
422                  if (value.controller_number == cc) {                  if (value.controller_number == cc) {
423                      x += 3;                      comboIndex = x;
424                      break;                      break;
425                  }                  }
426                    x++;
427              }              }
428          }          }
429          break;          break;
430        }
431      default:      default:
432          x = -1;          comboIndex = -1;
433          break;          break;
434      }      }
435      combobox.set_active(x);      combobox.set_active(comboIndex);
436  }  }
437    
438    
# Line 322  StringEntry::StringEntry(const char* lab Line 450  StringEntry::StringEntry(const char* lab
450      entry.signal_changed().connect(sig_changed.make_slot());      entry.signal_changed().connect(sig_changed.make_slot());
451  }  }
452    
453    gig::String StringEntry::get_value() const
454    {
455        return gig_from_utf8(entry.get_text());
456    }
457    
458    void StringEntry::set_value(const gig::String& value) {
459        entry.set_text(gig_to_utf8(value));
460    }
461    
462    
463  StringEntryMultiLine::StringEntryMultiLine(const char* labelText) :  StringEntryMultiLine::StringEntryMultiLine(const char* labelText) :
464      LabelWidget(labelText, frame)      LabelWidget(labelText, frame)
465  {  {
# Line 336  gig::String StringEntryMultiLine::get_va Line 474  gig::String StringEntryMultiLine::get_va
474      Glib::ustring value = text_buffer->get_text();      Glib::ustring value = text_buffer->get_text();
475      for (int i = 0 ; (i = value.find("\x0a", i)) >= 0 ; i += 2)      for (int i = 0 ; (i = value.find("\x0a", i)) >= 0 ; i += 2)
476          value.replace(i, 1, "\x0d\x0a");          value.replace(i, 1, "\x0d\x0a");
477      return value;      return gig_from_utf8(value);
478    }
479    
480    void StringEntryMultiLine::set_value(const gig::String& value)
481    {
482        Glib::ustring text = gig_to_utf8(value);
483        for (int i = 0 ; (i = text.find("\x0d\x0a", i, 2)) >= 0 ; i++)
484            text.replace(i, 2, "\x0a");
485        text_buffer->set_text(text);
486    }
487    
488    
489    Table::Table(int x, int y) : Gtk::Table(x, y), rowno(0) {  }
490    
491    void Table::add(BoolEntry& boolentry)
492    {
493        attach(boolentry.widget, 0, 2, rowno, rowno + 1,
494               Gtk::FILL, Gtk::SHRINK);
495        rowno++;
496    }
497    
498    void Table::add(BoolEntryPlus6& boolentry)
499    {
500        attach(boolentry.widget, 0, 2, rowno, rowno + 1,
501               Gtk::FILL, Gtk::SHRINK);
502        rowno++;
503  }  }
504    
505  void StringEntryMultiLine::set_value(gig::String value)  void Table::add(LabelWidget& prop)
506  {  {
507      for (int i = 0 ; (i = value.find("\x0d\x0a", i, 2)) >= 0 ; i++)      attach(prop.label, 1, 2, rowno, rowno + 1,
508          value.replace(i, 2, "\x0a");             Gtk::FILL, Gtk::SHRINK);
509      text_buffer->set_text(value);      attach(prop.widget, 2, 3, rowno, rowno + 1,
510               Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK);
511        rowno++;
512  }  }

Legend:
Removed from v.1831  
changed lines
  Added in v.2538

  ViewVC Help
Powered by ViewVC