/[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 3738 - (hide annotations) (download)
Mon Feb 3 18:47:02 2020 UTC (4 years, 2 months ago) by schoenebeck
File size: 21875 byte(s)
* Use more appropriate stepping/paging increments/decrements for spinboxes'
  plus/minus buttons (depending on the individual parameter spinbutton
  actually controls).

* Bumped version (1.1.1.svn15).

1 schoenebeck 1225 /*
2 persson 3460 * Copyright (C) 2006-2019 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 3202 #include "global.h"
21 schoenebeck 1225 #include "paramedit.h"
22    
23 persson 2169 #include "compat.h"
24 schoenebeck 2541 #include "Settings.h"
25 persson 1831
26 schoenebeck 3411 #ifdef GLIBMM_HEADER_FILE
27     # include GLIBMM_HEADER_FILE(glibmm.h)
28     #else
29     # include <glibmm.h>
30     #endif
31    
32 schoenebeck 2541 #include <gtkmm/messagedialog.h>
33    
34 schoenebeck 1225 namespace {
35 schoenebeck 2541 struct CCText {
36     const char* const txt;
37     bool isExtension; ///< True if this is a controller only supported by LinuxSampler, but not supperted by Gigasampler/GigaStudio.
38     };
39     static const CCText controlChangeTexts[] = {
40     // 3 special ones (not being CCs)
41     { _("none") }, { _("channelaftertouch") }, { _("velocity") },
42     {0}, // bank select MSB (hard coded in sampler, so discouraged to be used here, even though considerable)
43     { _("modwheel") }, // "Modulation Wheel or Lever",
44     { _("breath") }, // "Breath Controller",
45     { _("undefined"), true },
46     { _("foot") }, // "Foot Controller",
47     { _("portamentotime") }, // "Portamento Time",
48     { _("data entry MSB"), true },
49     { _("volume"), true },
50     { _("balance"), true },
51     { _("undefined"), true },
52     { _("pan"), true },
53     { _("expression"), true },
54     { _("effect1") }, // "Effect Control 1",
55     { _("effect2") }, // "Effect Control 2",
56     { _("undefined"), true },
57     { _("undefined"), true },
58     { _("genpurpose1") }, // "General Purpose Controller 1",
59     { _("genpurpose2") }, // "General Purpose Controller 2",
60     { _("genpurpose3") }, // "General Purpose Controller 3",
61     { _("genpurpose4") }, // "General Purpose Controller 4",
62     { _("undefined"), true },
63     { _("undefined"), true },
64     { _("undefined"), true },
65     { _("undefined"), true },
66     { _("undefined"), true },
67     { _("undefined"), true },
68     { _("undefined"), true },
69     { _("undefined"), true },
70     { _("undefined"), true },
71     { _("undefined"), true },
72     { _("undefined"), true },
73     { _("undefined"), true },
74 schoenebeck 2538
75     // LSB variant of the various controllers above
76     // (so discouraged to be used here for now)
77 schoenebeck 2541 {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}, {0}, {0},
79     {0}, {0}, {0}, {0},
80 schoenebeck 2538
81 schoenebeck 2541 { _("sustainpedal") }, // "Damper Pedal on/off (Sustain)",
82     { _("portamento") }, // "Portamento On/Off",
83     { _("sostenuto") }, // "Sustenuto On/Off",
84     { _("softpedal") }, // "Soft Pedal On/Off",
85     { _("legato"), true },
86     { _("hold2"), true },
87     { _("soundvariation"), true },
88     { _("timbre"), true },
89     { _("releasetime"), true },
90     { _("attacktime"), true },
91     { _("brightness"), true },
92     { _("decaytime"), true },
93     { _("vibratorate"), true },
94     { _("vibratodepth"), true },
95     { _("vibratodelay"), true },
96     { _("undefined"), true },
97     { _("genpurpose5") }, // "General Purpose Controller 5",
98     { _("genpurpose6") }, // "General Purpose Controller 6",
99     { _("genpurpose7") }, // "General Purpose Controller 7",
100     { _("genpurpose8") }, // "General Purpose Controller 8",
101     { _("portamentoctrl"), true },
102     { _("undefined"), true },
103     { _("undefined"), true },
104     { _("undefined"), true },
105     {0}, // high resolution velocity prefix (so discouraged to be used here)
106     { _("undefined"), true },
107     { _("undefined"), true },
108     { _("effect1depth") }, // "Effects 1 Depth",
109     { _("effect2depth") }, // "Effects 2 Depth",
110     { _("effect3depth") }, // "Effects 3 Depth",
111     { _("effect4depth") }, // "Effects 4 Depth",
112     { _("effect5depth") }, // "Effects 5 Depth"
113     { _("dataincrement"), true },
114     { _("datadecrement"), true },
115     {0}, // NRPN LSB (so discouraged to be used here)
116     {0}, // NRPN MSB (so discouraged to be used here)
117     {0}, // RPN LSB (so discouraged to be used here)
118     {0}, // RPN MSB (so discouraged to be used here)
119     { _("undefined"), true },
120     { _("undefined"), true },
121     { _("undefined"), true },
122     { _("undefined"), true },
123     { _("undefined"), true },
124     { _("undefined"), true },
125     { _("undefined"), true },
126     { _("undefined"), true },
127     { _("undefined"), true },
128     { _("undefined"), true },
129     { _("undefined"), true },
130     { _("undefined"), true },
131     { _("undefined"), true },
132     { _("undefined"), true },
133     { _("undefined"), true },
134     { _("undefined"), true },
135     { _("undefined"), true },
136     { _("undefined"), true } // CC 119
137 schoenebeck 2538 // (all other ones that follow [CC 120- CC 127] are hard coded channel
138     // mode messages, so those are discouraged to be used here)
139 schoenebeck 1225 };
140 schoenebeck 3624 static const char* const lfoWaveTexts[] = {
141     _("Sine"),
142     _("Triangle"),
143     _("Saw"),
144     _("Square"),
145     };
146 schoenebeck 1225 }
147    
148 schoenebeck 2541 #define controlChangeTextsSize (sizeof(controlChangeTexts) / sizeof(CCText))
149 schoenebeck 3624 #define lfoWaveTextsSize (sizeof(lfoWaveTexts) / sizeof(char*))
150 schoenebeck 2538
151 schoenebeck 1225 LabelWidget::LabelWidget(const char* labelText, Gtk::Widget& widget) :
152     label(Glib::ustring(labelText) + ":"),
153     widget(widget)
154     {
155 schoenebeck 3364 #if HAS_GTKMM_ALIGNMENT
156 persson 2169 label.set_alignment(Gtk::ALIGN_START);
157 schoenebeck 3364 #else
158     label.set_halign(Gtk::Align::START);
159     #endif
160 schoenebeck 3409 Settings::singleton()->showTooltips.get_proxy().signal_changed().connect(
161 persson 3461 sigc::mem_fun(*this, &LabelWidget::on_show_tooltips_changed)
162 schoenebeck 3409 );
163    
164     // workaround for a crash with certain gtkmm versions: postpone calling
165     // on_show_tooltips_changed() because widget.gobj() might be uninitialized
166     // at this point yet
167     Glib::signal_idle().connect_once( // timeout starts given amount of ms after the main loop became idle again ...
168     sigc::mem_fun(*this, &LabelWidget::on_show_tooltips_changed),
169     300
170     );
171 schoenebeck 1225 }
172    
173 schoenebeck 3409 void LabelWidget::on_show_tooltips_changed() {
174     const bool b = Settings::singleton()->showTooltips;
175     label.set_has_tooltip(b);
176     widget.set_has_tooltip(b);
177     }
178    
179 schoenebeck 1225 void LabelWidget::set_sensitive(bool sensitive)
180     {
181     label.set_sensitive(sensitive);
182     widget.set_sensitive(sensitive);
183     }
184    
185 schoenebeck 2690 ReadOnlyLabelWidget::ReadOnlyLabelWidget(const char* leftHandText)
186     : LabelWidget(leftHandText, text)
187     {
188 schoenebeck 3364 #if HAS_GTKMM_ALIGNMENT
189 schoenebeck 2690 text.set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_START);
190 schoenebeck 3364 #else
191     label.set_halign(Gtk::Align::START);
192     label.set_valign(Gtk::Align::START);
193     #endif
194 schoenebeck 2690 }
195    
196     ReadOnlyLabelWidget::ReadOnlyLabelWidget(const char* leftHandText, const char* rightHandText)
197     : LabelWidget(leftHandText, text)
198     {
199 schoenebeck 3364 #if HAS_GTKMM_ALIGNMENT
200 schoenebeck 2690 text.set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_START);
201 schoenebeck 3364 #else
202     text.set_halign(Gtk::Align::START);
203     text.set_valign(Gtk::Align::START);
204     #endif
205 schoenebeck 2690 text.set_text(rightHandText);
206     }
207    
208 schoenebeck 3738 static double stepForDecimals(int decimals) {
209     switch (decimals) {
210     case 0: return 1.0;
211     case 1: return 0.1;
212     case 2: default: return 0.01;
213     }
214     }
215    
216     static double pageForDecimals(int decimals) {
217     switch (decimals) {
218     case 0: return 10.0;
219     case 1: return 1.0;
220     case 2: default: return 0.1;
221     }
222     }
223    
224 schoenebeck 1225 NumEntry::NumEntry(const char* labelText, double lower, double upper,
225     int decimals) :
226 persson 2151 LabelWidget(labelText, box),
227 persson 2169 #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
228 schoenebeck 3738 adjust(lower, lower, upper, stepForDecimals(decimals), pageForDecimals(decimals)),
229 persson 2169 #else
230 schoenebeck 3738 adjust(Gtk::Adjustment::create(lower, lower, upper, stepForDecimals(decimals), pageForDecimals(decimals))),
231 persson 2169 #endif
232 schoenebeck 1225 scale(adjust),
233 persson 2151 spinbutton(adjust)
234 schoenebeck 1225 {
235 persson 2423 scale.set_size_request(70);
236 schoenebeck 1225 spinbutton.set_digits(decimals);
237 persson 1460 spinbutton.set_value(0);
238 persson 2507 spinbutton.set_numeric();
239 schoenebeck 1225 scale.set_draw_value(false);
240     box.pack_start(spinbutton, Gtk::PACK_SHRINK);
241     box.add(scale);
242     }
243    
244 schoenebeck 3409 void NumEntry::on_show_tooltips_changed() {
245     LabelWidget::on_show_tooltips_changed();
246    
247     const bool b = Settings::singleton()->showTooltips;
248     spinbutton.set_has_tooltip(b);
249     scale.set_has_tooltip(b);
250     }
251    
252 schoenebeck 1225 NumEntryGain::NumEntryGain(const char* labelText,
253     double lower, double upper,
254     int decimals, double coeff) :
255     NumEntry(labelText, lower, upper, decimals),
256 persson 2151 value(0),
257 persson 1460 coeff(coeff),
258     connected(true)
259 schoenebeck 1225 {
260 schoenebeck 3738 spinbutton.set_increments(0.1, 1.0);
261 schoenebeck 1225 spinbutton.signal_value_changed().connect(
262     sigc::mem_fun(*this, &NumEntryGain::value_changed));
263     }
264    
265     void NumEntryGain::value_changed()
266     {
267 persson 1460 if (!connected) return;
268    
269 schoenebeck 1359 const double f = pow(10, spinbutton.get_digits());
270     int new_value = round_to_int(spinbutton.get_value() * f);
271 persson 1460 if (new_value != round_to_int(value / coeff * f)) {
272     value = round_to_int(new_value / f * coeff);
273     sig_changed();
274 schoenebeck 1225 }
275     }
276    
277 persson 1460 void NumEntryGain::set_value(int32_t value)
278 schoenebeck 1225 {
279 persson 1460 if (value != this->value) {
280     this->value = value;
281    
282     connected = false;
283 schoenebeck 3643 spinbutton.set_value(value / coeff);
284 persson 1460 connected = true;
285    
286     sig_changed();
287     }
288 schoenebeck 1225 }
289    
290    
291     NumEntryPermille::NumEntryPermille(const char* labelText,
292     double lower, double upper, int decimals) :
293 persson 1460 NumEntry(labelText, lower, upper, decimals),
294     value(0)
295 schoenebeck 1225 {
296     spinbutton.signal_value_changed().connect(
297     sigc::mem_fun(*this, &NumEntryPermille::value_changed));
298     }
299    
300     void NumEntryPermille::value_changed()
301     {
302 persson 1460 uint16_t new_value = uint16_t(spinbutton.get_value() * 10 + 0.5);
303     if (new_value != value) {
304     value = uint16_t(spinbutton.get_value() * 10 + 0.5);
305     sig_changed();
306 schoenebeck 1225 }
307     }
308    
309 persson 1460 void NumEntryPermille::set_value(uint16_t value)
310 schoenebeck 1225 {
311 persson 1460 if (value != this->value) {
312     spinbutton.set_value(value / 10.0);
313     }
314 schoenebeck 1225 }
315    
316    
317     NoteEntry::NoteEntry(const char* labelText) :
318     NumEntryTemp<uint8_t>(labelText)
319     {
320 persson 2507 spin_button_show_notes(spinbutton);
321 schoenebeck 1225 }
322    
323 persson 2507 namespace {
324     const char* notes[] = {
325     _("C"), _("C#"), _("D"), _("D#"), _("E"), _("F"),_("F#"),
326     _("G"), _("G#"), _("A"), _("A#"), _("B")
327     };
328 schoenebeck 1225
329 persson 2507 int note_value(const Glib::ustring& note, double* value)
330     {
331     const char* str = note.c_str();
332 schoenebeck 1225
333 persson 2507 int i;
334     for (i = 11 ; i >= 0 ; i--) {
335     if (strncasecmp(str, notes[i], strlen(notes[i])) == 0) break;
336     }
337     if (i >= 0) {
338     char* endptr;
339     long x = strtol(str + strlen(notes[i]), &endptr, 10);
340     if (endptr != str + strlen(notes[i])) {
341     *value = std::max(0L, std::min(i + (x + 1) * 12, 127L));
342     return true;
343     }
344     } else {
345     char* endptr;
346     long x = strtol(str, &endptr, 10);
347     if (endptr != str) {
348     *value = std::max(0L, std::min(x, 127L));
349     return true;
350     }
351     }
352 schoenebeck 3364
353     #if HAS_GTKMM_CPP11_ENUMS
354     return Gtk::SpinButton::INPUT_ERROR;
355     #else
356 persson 2507 return Gtk::INPUT_ERROR;
357 schoenebeck 3364 #endif
358 persson 2507 }
359     }
360    
361     int note_value(const Glib::ustring& note)
362 schoenebeck 1225 {
363 persson 2507 double value = 0;
364     note_value(note, &value);
365     return value;
366     }
367 schoenebeck 1225
368 persson 2507 Glib::ustring note_str(int note)
369     {
370     char buf[10];
371     sprintf(buf, "%s%d", notes[note % 12], note / 12 - 1);
372     return buf;
373     }
374    
375     namespace {
376     // Convert the Entry text to a number
377 schoenebeck 3364 #if GTKMM_MAJOR_VERSION > 3 || (GTKMM_MAJOR_VERSION == 3 && (GTKMM_MINOR_VERSION > 91 || (GTKMM_MINOR_VERSION == 91 && GTKMM_MICRO_VERSION >= 2))) // GTKMM >= 3.91.2
378     int on_input(double& new_value, Gtk::SpinButton* spinbutton) {
379     return note_value(spinbutton->get_text(), &new_value);
380     }
381     #else
382 persson 2507 int on_input(double* new_value, Gtk::SpinButton* spinbutton) {
383     return note_value(spinbutton->get_text(), new_value);
384 schoenebeck 1225 }
385 schoenebeck 3364 #endif
386 persson 2507
387     // Convert the Adjustment position to text
388     bool on_output(Gtk::SpinButton* spinbutton) {
389     spinbutton->set_text(
390     note_str(spinbutton->get_adjustment()->get_value() + 0.5));
391     return true;
392 schoenebeck 1225 }
393     }
394    
395 persson 2507 // Make a SpinButton show notes instead of numbers
396     void spin_button_show_notes(Gtk::SpinButton& spin_button)
397 schoenebeck 1225 {
398 persson 2507 spin_button.set_numeric(false);
399     spin_button.set_width_chars(4);
400     spin_button.signal_input().connect(
401     sigc::bind(sigc::ptr_fun(&on_input), &spin_button));
402     spin_button.signal_output().connect(
403     sigc::bind(sigc::ptr_fun(&on_output), &spin_button));
404 schoenebeck 1225 }
405    
406 schoenebeck 3409 void ChoiceEntryBase::on_show_tooltips_changed() {
407     LabelWidget::on_show_tooltips_changed();
408    
409     const bool b = Settings::singleton()->showTooltips;
410     combobox.set_has_tooltip(b);
411     }
412    
413 schoenebeck 1225 ChoiceEntryLeverageCtrl::ChoiceEntryLeverageCtrl(const char* labelText) :
414 schoenebeck 3364 #if HAS_GTKMM_ALIGNMENT
415 persson 2151 LabelWidget(labelText, align),
416     align(0, 0, 0, 0)
417 schoenebeck 3364 #else
418     LabelWidget(labelText, combobox)
419     #endif
420 schoenebeck 1225 {
421 schoenebeck 2538 for (int i = 0 ; i < controlChangeTextsSize ; i++) {
422 schoenebeck 2541 if (controlChangeTexts[i].txt) {
423 schoenebeck 2538 const int cc = i - 3;
424     Glib::ustring s = (i < 3)
425 schoenebeck 2541 ? controlChangeTexts[i].txt
426     : Glib::ustring::compose("CC%1: %2%3", cc, controlChangeTexts[i].txt, controlChangeTexts[i].isExtension ? " [EXT]" : "");
427 persson 2507 #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 24) || GTKMM_MAJOR_VERSION < 2
428 schoenebeck 2538 combobox.append_text(s);
429 persson 2169 #else
430 schoenebeck 2538 combobox.append(s);
431 persson 2169 #endif
432 schoenebeck 1225 }
433     }
434 persson 3460 combobox.set_wrap_width(4);
435 schoenebeck 1225 combobox.signal_changed().connect(
436     sigc::mem_fun(*this, &ChoiceEntryLeverageCtrl::value_changed));
437 schoenebeck 3364 #if HAS_GTKMM_ALIGNMENT
438 schoenebeck 1225 align.add(combobox);
439 schoenebeck 3364 #else
440     combobox.set_halign(Gtk::Align::FILL);
441     combobox.set_valign(Gtk::Align::FILL);
442     #endif
443 persson 1460 value.type = gig::leverage_ctrl_t::type_none;
444     value.controller_number = 0;
445 schoenebeck 1225 }
446    
447 schoenebeck 3409 void ChoiceEntryLeverageCtrl::on_show_tooltips_changed() {
448     LabelWidget::on_show_tooltips_changed();
449    
450     const bool b = Settings::singleton()->showTooltips;
451     combobox.set_has_tooltip(b);
452     }
453    
454 schoenebeck 3624 static void _showGigFormatExtWarning() {
455     if (!Settings::singleton()->warnUserOnExtensions) return;
456     Glib::ustring txt =
457     _("<b>Format Extension</b>\n\nAll options marked with \"<b>[EXT]</b>\" are an extension to the original gig sound format. They will only work with LinuxSampler, but they will <b>not work</b> with Gigasampler/GigaStudio!\n\n(You may disable this warning in the <i>Settings</i> menu.)");
458     Gtk::MessageDialog msg(txt, true, Gtk::MESSAGE_WARNING);
459     msg.run();
460     }
461    
462 schoenebeck 1225 void ChoiceEntryLeverageCtrl::value_changed()
463     {
464 persson 1460 int rowno = combobox.get_active_row_number();
465     switch (rowno)
466     {
467     case -1:
468     break;
469     case 0:
470     value.type = gig::leverage_ctrl_t::type_none;
471     break;
472     case 1:
473     value.type = gig::leverage_ctrl_t::type_channelaftertouch;
474     break;
475     case 2:
476     value.type = gig::leverage_ctrl_t::type_velocity;
477     break;
478     default:
479     value.type = gig::leverage_ctrl_t::type_controlchange;
480     int x = 3;
481 schoenebeck 2538 for (uint cc = 0 ; cc < controlChangeTextsSize - 3 ; cc++) {
482 schoenebeck 2541 if (controlChangeTexts[cc + 3].txt) {
483 persson 1460 if (rowno == x) {
484     value.controller_number = cc;
485 schoenebeck 3624 if (controlChangeTexts[cc + 3].isExtension) {
486     _showGigFormatExtWarning();
487 schoenebeck 2541 }
488 persson 1460 break;
489 schoenebeck 1225 }
490 persson 1460 x++;
491 schoenebeck 1225 }
492     }
493 persson 1460 break;
494 schoenebeck 1225 }
495 persson 1460 if (rowno >= 0) sig_changed();
496 schoenebeck 1225 }
497    
498 persson 1460 void ChoiceEntryLeverageCtrl::set_value(gig::leverage_ctrl_t value)
499 schoenebeck 1225 {
500 schoenebeck 2538 int comboIndex;
501 persson 1460 switch (value.type)
502 schoenebeck 1225 {
503     case gig::leverage_ctrl_t::type_none:
504 schoenebeck 2538 comboIndex = 0;
505 schoenebeck 1225 break;
506     case gig::leverage_ctrl_t::type_channelaftertouch:
507 schoenebeck 2538 comboIndex = 1;
508 schoenebeck 1225 break;
509     case gig::leverage_ctrl_t::type_velocity:
510 schoenebeck 2538 comboIndex = 2;
511 schoenebeck 1225 break;
512 schoenebeck 2538 case gig::leverage_ctrl_t::type_controlchange: {
513     comboIndex = -1;
514     int x = 3;
515     for (uint cc = 0 ; cc < controlChangeTextsSize - 3 ; cc++) {
516 schoenebeck 2541 if (controlChangeTexts[cc + 3].txt) {
517 persson 1460 if (value.controller_number == cc) {
518 schoenebeck 2538 comboIndex = x;
519 schoenebeck 1225 break;
520     }
521 schoenebeck 2538 x++;
522 schoenebeck 1225 }
523     }
524     break;
525 schoenebeck 2538 }
526 schoenebeck 1225 default:
527 schoenebeck 2538 comboIndex = -1;
528 schoenebeck 1225 break;
529     }
530 schoenebeck 2538 combobox.set_active(comboIndex);
531 schoenebeck 1225 }
532    
533    
534 schoenebeck 3624 ChoiceEntryLfoWave::ChoiceEntryLfoWave(const char* labelText) :
535     #if HAS_GTKMM_ALIGNMENT
536     LabelWidget(labelText, align),
537     align(0, 0, 0, 0)
538     #else
539     LabelWidget(labelText, combobox)
540     #endif
541     {
542     for (int i = 0 ; i < lfoWaveTextsSize; i++) {
543     if (lfoWaveTexts[i]) {
544     Glib::ustring s = (i == 0)
545     ? lfoWaveTexts[i]
546     : Glib::ustring::compose("%1 [EXT]", lfoWaveTexts[i]);
547     #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 24) || GTKMM_MAJOR_VERSION < 2
548     combobox.append_text(s);
549     #else
550     combobox.append(s);
551     #endif
552     }
553     }
554     //combobox.set_wrap_width(4);
555     combobox.signal_changed().connect(
556     sigc::mem_fun(*this, &ChoiceEntryLfoWave::value_changed));
557     #if HAS_GTKMM_ALIGNMENT
558     align.add(combobox);
559     #else
560     combobox.set_halign(Gtk::Align::FILL);
561     combobox.set_valign(Gtk::Align::FILL);
562     #endif
563     value = gig::lfo_wave_sine;
564     }
565    
566     void ChoiceEntryLfoWave::on_show_tooltips_changed() {
567     LabelWidget::on_show_tooltips_changed();
568    
569     const bool b = Settings::singleton()->showTooltips;
570     combobox.set_has_tooltip(b);
571     }
572    
573     void ChoiceEntryLfoWave::value_changed() {
574     const int rowno = combobox.get_active_row_number();
575     switch (rowno) {
576     case -1:
577     break;
578     case 0:
579     value = gig::lfo_wave_sine;
580     break;
581     case 1:
582     value = gig::lfo_wave_triangle;
583     _showGigFormatExtWarning();
584     break;
585     case 2:
586     value = gig::lfo_wave_saw;
587     _showGigFormatExtWarning();
588     break;
589     case 3:
590     value = gig::lfo_wave_square;
591     _showGigFormatExtWarning();
592     break;
593     }
594     if (rowno >= 0) sig_changed();
595     }
596    
597     void ChoiceEntryLfoWave::set_value(gig::lfo_wave_t value) {
598     int comboIndex;
599     switch (value) {
600     case gig::lfo_wave_sine:
601     comboIndex = 0;
602     break;
603     case gig::lfo_wave_triangle:
604     comboIndex = 1;
605     break;
606     case gig::lfo_wave_saw:
607     comboIndex = 2;
608     break;
609     case gig::lfo_wave_square:
610     comboIndex = 3;
611     break;
612     default:
613     comboIndex = -1;
614     break;
615     }
616     combobox.set_active(comboIndex);
617     }
618    
619    
620 schoenebeck 3409 BoolBox::BoolBox(const char* labelText) : Gtk::CheckButton(labelText) {
621     signal_toggled().connect(sig_changed.make_slot());
622     Settings::singleton()->showTooltips.get_proxy().signal_changed().connect(
623 persson 3461 sigc::mem_fun(*this, &BoolBox::on_show_tooltips_changed)
624 schoenebeck 3409 );
625     on_show_tooltips_changed();
626     }
627    
628     void BoolBox::on_show_tooltips_changed() {
629     const bool b = Settings::singleton()->showTooltips;
630     set_has_tooltip(b);
631     }
632    
633    
634 schoenebeck 1225 BoolEntry::BoolEntry(const char* labelText) :
635     LabelWidget(labelText, checkbutton),
636 persson 1460 checkbutton(labelText)
637 schoenebeck 1225 {
638 persson 1460 checkbutton.signal_toggled().connect(sig_changed.make_slot());
639 schoenebeck 1225 }
640    
641    
642     StringEntry::StringEntry(const char* labelText) :
643     LabelWidget(labelText, entry)
644     {
645 persson 1582 entry.signal_changed().connect(sig_changed.make_slot());
646 schoenebeck 1225 }
647    
648 persson 2446 gig::String StringEntry::get_value() const
649     {
650     return gig_from_utf8(entry.get_text());
651     }
652    
653     void StringEntry::set_value(const gig::String& value) {
654     entry.set_text(gig_to_utf8(value));
655     }
656    
657    
658 persson 1582 StringEntryMultiLine::StringEntryMultiLine(const char* labelText) :
659     LabelWidget(labelText, frame)
660 schoenebeck 1225 {
661 persson 1582 text_buffer = text_view.get_buffer();
662     frame.set_shadow_type(Gtk::SHADOW_IN);
663     frame.add(text_view);
664     text_buffer->signal_changed().connect(sig_changed.make_slot());
665 schoenebeck 1225 }
666    
667 persson 1582 gig::String StringEntryMultiLine::get_value() const
668 schoenebeck 1225 {
669 persson 1582 Glib::ustring value = text_buffer->get_text();
670     for (int i = 0 ; (i = value.find("\x0a", i)) >= 0 ; i += 2)
671     value.replace(i, 1, "\x0d\x0a");
672 persson 2446 return gig_from_utf8(value);
673 schoenebeck 1225 }
674 persson 1582
675 persson 2446 void StringEntryMultiLine::set_value(const gig::String& value)
676 persson 1582 {
677 persson 2446 Glib::ustring text = gig_to_utf8(value);
678     for (int i = 0 ; (i = text.find("\x0d\x0a", i, 2)) >= 0 ; i++)
679     text.replace(i, 2, "\x0a");
680     text_buffer->set_text(text);
681 persson 1582 }
682 persson 2423
683 schoenebeck 3409 void StringEntryMultiLine::on_show_tooltips_changed() {
684     LabelWidget::on_show_tooltips_changed();
685 persson 2423
686 schoenebeck 3409 const bool b = Settings::singleton()->showTooltips;
687     text_view.set_has_tooltip(b);
688     }
689    
690    
691 schoenebeck 3364 Table::Table(int x, int y) :
692     #if USE_GTKMM_GRID
693     Gtk::Grid(),
694     cols(x),
695     #else
696     Gtk::Table(x, y),
697     #endif
698     rowno(0)
699     {
700     }
701 persson 2423
702     void Table::add(BoolEntry& boolentry)
703     {
704 schoenebeck 3364 #if USE_GTKMM_GRID
705     attach(boolentry.widget, 0, rowno, 2);
706     #else
707 persson 2423 attach(boolentry.widget, 0, 2, rowno, rowno + 1,
708     Gtk::FILL, Gtk::SHRINK);
709 schoenebeck 3364 #endif
710 persson 2423 rowno++;
711     }
712    
713     void Table::add(LabelWidget& prop)
714     {
715 schoenebeck 3364 #if USE_GTKMM_GRID
716     attach(prop.label, 1, rowno);
717     attach(prop.widget, 2, rowno);
718     #else
719 persson 2423 attach(prop.label, 1, 2, rowno, rowno + 1,
720     Gtk::FILL, Gtk::SHRINK);
721     attach(prop.widget, 2, 3, rowno, rowno + 1,
722     Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK);
723 schoenebeck 3364 #endif
724 persson 2423 rowno++;
725     }

  ViewVC Help
Powered by ViewVC