/[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 3624 - (show annotations) (download)
Wed Oct 2 17:11:30 2019 UTC (6 months ago) by schoenebeck
File size: 22480 byte(s)
* GIG SOUND FORMAT EXTENSION: Added combo box for selecting a wave form
  type for each one of the 3 LFOs (i.e. for overriding the default LFO
  sine wave form to either triangle, saw or square instead).

* GIG SOUND FORMAT EXTENSION: Added slider for each one of the 3 LFOs
  for altering the phase displacement of the respective LFO (that is
  for moving the LFO's start level horizontally on the time axis).

* GIG SOUND FORMAT EXTENSION: Added checkbox "Flip Phase" to LFO 3
  (the original Gigasampler/GigaStudio software only supported that
  option for LFO 1 and LFO 2).

* Bumped version (1.1.1.svn3).

1 /*
2 * Copyright (C) 2006-2019 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 "global.h"
21 #include "paramedit.h"
22
23 #include "compat.h"
24 #include "Settings.h"
25
26 #ifdef GLIBMM_HEADER_FILE
27 # include GLIBMM_HEADER_FILE(glibmm.h)
28 #else
29 # include <glibmm.h>
30 #endif
31
32 #include <gtkmm/messagedialog.h>
33
34 namespace {
35 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
75 // LSB variant of the various controllers above
76 // (so discouraged to be used here for now)
77 {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
81 { _("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 // (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 };
140 static const char* const lfoWaveTexts[] = {
141 _("Sine"),
142 _("Triangle"),
143 _("Saw"),
144 _("Square"),
145 };
146 }
147
148 #define controlChangeTextsSize (sizeof(controlChangeTexts) / sizeof(CCText))
149 #define lfoWaveTextsSize (sizeof(lfoWaveTexts) / sizeof(char*))
150
151 LabelWidget::LabelWidget(const char* labelText, Gtk::Widget& widget) :
152 label(Glib::ustring(labelText) + ":"),
153 widget(widget)
154 {
155 #if HAS_GTKMM_ALIGNMENT
156 label.set_alignment(Gtk::ALIGN_START);
157 #else
158 label.set_halign(Gtk::Align::START);
159 #endif
160 Settings::singleton()->showTooltips.get_proxy().signal_changed().connect(
161 sigc::mem_fun(*this, &LabelWidget::on_show_tooltips_changed)
162 );
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 }
172
173 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 void LabelWidget::set_sensitive(bool sensitive)
180 {
181 label.set_sensitive(sensitive);
182 widget.set_sensitive(sensitive);
183 }
184
185 ReadOnlyLabelWidget::ReadOnlyLabelWidget(const char* leftHandText)
186 : LabelWidget(leftHandText, text)
187 {
188 #if HAS_GTKMM_ALIGNMENT
189 text.set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_START);
190 #else
191 label.set_halign(Gtk::Align::START);
192 label.set_valign(Gtk::Align::START);
193 #endif
194 }
195
196 ReadOnlyLabelWidget::ReadOnlyLabelWidget(const char* leftHandText, const char* rightHandText)
197 : LabelWidget(leftHandText, text)
198 {
199 #if HAS_GTKMM_ALIGNMENT
200 text.set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_START);
201 #else
202 text.set_halign(Gtk::Align::START);
203 text.set_valign(Gtk::Align::START);
204 #endif
205 text.set_text(rightHandText);
206 }
207
208 NumEntry::NumEntry(const char* labelText, double lower, double upper,
209 int decimals) :
210 LabelWidget(labelText, box),
211 #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
212 adjust(lower, lower, upper, 1, 10),
213 #else
214 adjust(Gtk::Adjustment::create(lower, lower, upper, 1, 10)),
215 #endif
216 scale(adjust),
217 spinbutton(adjust)
218 {
219 scale.set_size_request(70);
220 spinbutton.set_digits(decimals);
221 spinbutton.set_value(0);
222 spinbutton.set_numeric();
223 scale.set_draw_value(false);
224 box.pack_start(spinbutton, Gtk::PACK_SHRINK);
225 box.add(scale);
226 }
227
228 void NumEntry::on_show_tooltips_changed() {
229 LabelWidget::on_show_tooltips_changed();
230
231 const bool b = Settings::singleton()->showTooltips;
232 spinbutton.set_has_tooltip(b);
233 scale.set_has_tooltip(b);
234 }
235
236 NumEntryGain::NumEntryGain(const char* labelText,
237 double lower, double upper,
238 int decimals, double coeff) :
239 NumEntry(labelText, lower, upper, decimals),
240 value(0),
241 coeff(coeff),
242 connected(true)
243 {
244 spinbutton.signal_value_changed().connect(
245 sigc::mem_fun(*this, &NumEntryGain::value_changed));
246 }
247
248 void NumEntryGain::value_changed()
249 {
250 if (!connected) return;
251
252 const double f = pow(10, spinbutton.get_digits());
253 int new_value = round_to_int(spinbutton.get_value() * f);
254 if (new_value != round_to_int(value / coeff * f)) {
255 value = round_to_int(new_value / f * coeff);
256 sig_changed();
257 }
258 }
259
260 void NumEntryGain::set_value(int32_t value)
261 {
262 if (value != this->value) {
263 this->value = value;
264
265 connected = false;
266 bool plus6 = value < 0;
267 spinbutton.set_value(plus6 ? 0 : value / coeff);
268 set_sensitive(!plus6);
269 connected = true;
270
271 sig_changed();
272 }
273 }
274
275
276 BoolEntryPlus6::BoolEntryPlus6(const char* labelText, NumEntryGain& eGain, int32_t plus6value) :
277 LabelWidget(labelText, checkbutton),
278 checkbutton(labelText),
279 eGain(eGain),
280 plus6value(plus6value)
281 {
282 checkbutton.signal_toggled().connect(
283 sigc::mem_fun(*this, &BoolEntryPlus6::value_changed));
284 }
285
286 void BoolEntryPlus6::on_show_tooltips_changed() {
287 LabelWidget::on_show_tooltips_changed();
288
289 eGain.on_show_tooltips_changed();
290 }
291
292 void BoolEntryPlus6::value_changed()
293 {
294 if (checkbutton.get_active()) eGain.set_value(plus6value);
295 else if (eGain.get_value() < 0) eGain.set_value(0);
296 }
297
298 int32_t BoolEntryPlus6::get_value() const
299 {
300 return eGain.get_value();
301 }
302
303 void BoolEntryPlus6::set_value(int32_t value)
304 {
305 checkbutton.set_active(value < 0);
306 }
307
308 NumEntryPermille::NumEntryPermille(const char* labelText,
309 double lower, double upper, int decimals) :
310 NumEntry(labelText, lower, upper, decimals),
311 value(0)
312 {
313 spinbutton.signal_value_changed().connect(
314 sigc::mem_fun(*this, &NumEntryPermille::value_changed));
315 }
316
317 void NumEntryPermille::value_changed()
318 {
319 uint16_t new_value = uint16_t(spinbutton.get_value() * 10 + 0.5);
320 if (new_value != value) {
321 value = uint16_t(spinbutton.get_value() * 10 + 0.5);
322 sig_changed();
323 }
324 }
325
326 void NumEntryPermille::set_value(uint16_t value)
327 {
328 if (value != this->value) {
329 spinbutton.set_value(value / 10.0);
330 }
331 }
332
333
334 NoteEntry::NoteEntry(const char* labelText) :
335 NumEntryTemp<uint8_t>(labelText)
336 {
337 spin_button_show_notes(spinbutton);
338 }
339
340 namespace {
341 const char* notes[] = {
342 _("C"), _("C#"), _("D"), _("D#"), _("E"), _("F"),_("F#"),
343 _("G"), _("G#"), _("A"), _("A#"), _("B")
344 };
345
346 int note_value(const Glib::ustring& note, double* value)
347 {
348 const char* str = note.c_str();
349
350 int i;
351 for (i = 11 ; i >= 0 ; i--) {
352 if (strncasecmp(str, notes[i], strlen(notes[i])) == 0) break;
353 }
354 if (i >= 0) {
355 char* endptr;
356 long x = strtol(str + strlen(notes[i]), &endptr, 10);
357 if (endptr != str + strlen(notes[i])) {
358 *value = std::max(0L, std::min(i + (x + 1) * 12, 127L));
359 return true;
360 }
361 } else {
362 char* endptr;
363 long x = strtol(str, &endptr, 10);
364 if (endptr != str) {
365 *value = std::max(0L, std::min(x, 127L));
366 return true;
367 }
368 }
369
370 #if HAS_GTKMM_CPP11_ENUMS
371 return Gtk::SpinButton::INPUT_ERROR;
372 #else
373 return Gtk::INPUT_ERROR;
374 #endif
375 }
376 }
377
378 int note_value(const Glib::ustring& note)
379 {
380 double value = 0;
381 note_value(note, &value);
382 return value;
383 }
384
385 Glib::ustring note_str(int note)
386 {
387 char buf[10];
388 sprintf(buf, "%s%d", notes[note % 12], note / 12 - 1);
389 return buf;
390 }
391
392 namespace {
393 // Convert the Entry text to a number
394 #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
395 int on_input(double& new_value, Gtk::SpinButton* spinbutton) {
396 return note_value(spinbutton->get_text(), &new_value);
397 }
398 #else
399 int on_input(double* new_value, Gtk::SpinButton* spinbutton) {
400 return note_value(spinbutton->get_text(), new_value);
401 }
402 #endif
403
404 // Convert the Adjustment position to text
405 bool on_output(Gtk::SpinButton* spinbutton) {
406 spinbutton->set_text(
407 note_str(spinbutton->get_adjustment()->get_value() + 0.5));
408 return true;
409 }
410 }
411
412 // Make a SpinButton show notes instead of numbers
413 void spin_button_show_notes(Gtk::SpinButton& spin_button)
414 {
415 spin_button.set_numeric(false);
416 spin_button.set_width_chars(4);
417 spin_button.signal_input().connect(
418 sigc::bind(sigc::ptr_fun(&on_input), &spin_button));
419 spin_button.signal_output().connect(
420 sigc::bind(sigc::ptr_fun(&on_output), &spin_button));
421 }
422
423 void ChoiceEntryBase::on_show_tooltips_changed() {
424 LabelWidget::on_show_tooltips_changed();
425
426 const bool b = Settings::singleton()->showTooltips;
427 combobox.set_has_tooltip(b);
428 }
429
430 ChoiceEntryLeverageCtrl::ChoiceEntryLeverageCtrl(const char* labelText) :
431 #if HAS_GTKMM_ALIGNMENT
432 LabelWidget(labelText, align),
433 align(0, 0, 0, 0)
434 #else
435 LabelWidget(labelText, combobox)
436 #endif
437 {
438 for (int i = 0 ; i < controlChangeTextsSize ; i++) {
439 if (controlChangeTexts[i].txt) {
440 const int cc = i - 3;
441 Glib::ustring s = (i < 3)
442 ? controlChangeTexts[i].txt
443 : Glib::ustring::compose("CC%1: %2%3", cc, controlChangeTexts[i].txt, controlChangeTexts[i].isExtension ? " [EXT]" : "");
444 #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 24) || GTKMM_MAJOR_VERSION < 2
445 combobox.append_text(s);
446 #else
447 combobox.append(s);
448 #endif
449 }
450 }
451 combobox.set_wrap_width(4);
452 combobox.signal_changed().connect(
453 sigc::mem_fun(*this, &ChoiceEntryLeverageCtrl::value_changed));
454 #if HAS_GTKMM_ALIGNMENT
455 align.add(combobox);
456 #else
457 combobox.set_halign(Gtk::Align::FILL);
458 combobox.set_valign(Gtk::Align::FILL);
459 #endif
460 value.type = gig::leverage_ctrl_t::type_none;
461 value.controller_number = 0;
462 }
463
464 void ChoiceEntryLeverageCtrl::on_show_tooltips_changed() {
465 LabelWidget::on_show_tooltips_changed();
466
467 const bool b = Settings::singleton()->showTooltips;
468 combobox.set_has_tooltip(b);
469 }
470
471 static void _showGigFormatExtWarning() {
472 if (!Settings::singleton()->warnUserOnExtensions) return;
473 Glib::ustring txt =
474 _("<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.)");
475 Gtk::MessageDialog msg(txt, true, Gtk::MESSAGE_WARNING);
476 msg.run();
477 }
478
479 void ChoiceEntryLeverageCtrl::value_changed()
480 {
481 int rowno = combobox.get_active_row_number();
482 switch (rowno)
483 {
484 case -1:
485 break;
486 case 0:
487 value.type = gig::leverage_ctrl_t::type_none;
488 break;
489 case 1:
490 value.type = gig::leverage_ctrl_t::type_channelaftertouch;
491 break;
492 case 2:
493 value.type = gig::leverage_ctrl_t::type_velocity;
494 break;
495 default:
496 value.type = gig::leverage_ctrl_t::type_controlchange;
497 int x = 3;
498 for (uint cc = 0 ; cc < controlChangeTextsSize - 3 ; cc++) {
499 if (controlChangeTexts[cc + 3].txt) {
500 if (rowno == x) {
501 value.controller_number = cc;
502 if (controlChangeTexts[cc + 3].isExtension) {
503 _showGigFormatExtWarning();
504 }
505 break;
506 }
507 x++;
508 }
509 }
510 break;
511 }
512 if (rowno >= 0) sig_changed();
513 }
514
515 void ChoiceEntryLeverageCtrl::set_value(gig::leverage_ctrl_t value)
516 {
517 int comboIndex;
518 switch (value.type)
519 {
520 case gig::leverage_ctrl_t::type_none:
521 comboIndex = 0;
522 break;
523 case gig::leverage_ctrl_t::type_channelaftertouch:
524 comboIndex = 1;
525 break;
526 case gig::leverage_ctrl_t::type_velocity:
527 comboIndex = 2;
528 break;
529 case gig::leverage_ctrl_t::type_controlchange: {
530 comboIndex = -1;
531 int x = 3;
532 for (uint cc = 0 ; cc < controlChangeTextsSize - 3 ; cc++) {
533 if (controlChangeTexts[cc + 3].txt) {
534 if (value.controller_number == cc) {
535 comboIndex = x;
536 break;
537 }
538 x++;
539 }
540 }
541 break;
542 }
543 default:
544 comboIndex = -1;
545 break;
546 }
547 combobox.set_active(comboIndex);
548 }
549
550
551 ChoiceEntryLfoWave::ChoiceEntryLfoWave(const char* labelText) :
552 #if HAS_GTKMM_ALIGNMENT
553 LabelWidget(labelText, align),
554 align(0, 0, 0, 0)
555 #else
556 LabelWidget(labelText, combobox)
557 #endif
558 {
559 for (int i = 0 ; i < lfoWaveTextsSize; i++) {
560 if (lfoWaveTexts[i]) {
561 Glib::ustring s = (i == 0)
562 ? lfoWaveTexts[i]
563 : Glib::ustring::compose("%1 [EXT]", lfoWaveTexts[i]);
564 #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 24) || GTKMM_MAJOR_VERSION < 2
565 combobox.append_text(s);
566 #else
567 combobox.append(s);
568 #endif
569 }
570 }
571 //combobox.set_wrap_width(4);
572 combobox.signal_changed().connect(
573 sigc::mem_fun(*this, &ChoiceEntryLfoWave::value_changed));
574 #if HAS_GTKMM_ALIGNMENT
575 align.add(combobox);
576 #else
577 combobox.set_halign(Gtk::Align::FILL);
578 combobox.set_valign(Gtk::Align::FILL);
579 #endif
580 value = gig::lfo_wave_sine;
581 }
582
583 void ChoiceEntryLfoWave::on_show_tooltips_changed() {
584 LabelWidget::on_show_tooltips_changed();
585
586 const bool b = Settings::singleton()->showTooltips;
587 combobox.set_has_tooltip(b);
588 }
589
590 void ChoiceEntryLfoWave::value_changed() {
591 const int rowno = combobox.get_active_row_number();
592 switch (rowno) {
593 case -1:
594 break;
595 case 0:
596 value = gig::lfo_wave_sine;
597 break;
598 case 1:
599 value = gig::lfo_wave_triangle;
600 _showGigFormatExtWarning();
601 break;
602 case 2:
603 value = gig::lfo_wave_saw;
604 _showGigFormatExtWarning();
605 break;
606 case 3:
607 value = gig::lfo_wave_square;
608 _showGigFormatExtWarning();
609 break;
610 }
611 if (rowno >= 0) sig_changed();
612 }
613
614 void ChoiceEntryLfoWave::set_value(gig::lfo_wave_t value) {
615 int comboIndex;
616 switch (value) {
617 case gig::lfo_wave_sine:
618 comboIndex = 0;
619 break;
620 case gig::lfo_wave_triangle:
621 comboIndex = 1;
622 break;
623 case gig::lfo_wave_saw:
624 comboIndex = 2;
625 break;
626 case gig::lfo_wave_square:
627 comboIndex = 3;
628 break;
629 default:
630 comboIndex = -1;
631 break;
632 }
633 combobox.set_active(comboIndex);
634 }
635
636
637 BoolBox::BoolBox(const char* labelText) : Gtk::CheckButton(labelText) {
638 signal_toggled().connect(sig_changed.make_slot());
639 Settings::singleton()->showTooltips.get_proxy().signal_changed().connect(
640 sigc::mem_fun(*this, &BoolBox::on_show_tooltips_changed)
641 );
642 on_show_tooltips_changed();
643 }
644
645 void BoolBox::on_show_tooltips_changed() {
646 const bool b = Settings::singleton()->showTooltips;
647 set_has_tooltip(b);
648 }
649
650
651 BoolEntry::BoolEntry(const char* labelText) :
652 LabelWidget(labelText, checkbutton),
653 checkbutton(labelText)
654 {
655 checkbutton.signal_toggled().connect(sig_changed.make_slot());
656 }
657
658
659 StringEntry::StringEntry(const char* labelText) :
660 LabelWidget(labelText, entry)
661 {
662 entry.signal_changed().connect(sig_changed.make_slot());
663 }
664
665 gig::String StringEntry::get_value() const
666 {
667 return gig_from_utf8(entry.get_text());
668 }
669
670 void StringEntry::set_value(const gig::String& value) {
671 entry.set_text(gig_to_utf8(value));
672 }
673
674
675 StringEntryMultiLine::StringEntryMultiLine(const char* labelText) :
676 LabelWidget(labelText, frame)
677 {
678 text_buffer = text_view.get_buffer();
679 frame.set_shadow_type(Gtk::SHADOW_IN);
680 frame.add(text_view);
681 text_buffer->signal_changed().connect(sig_changed.make_slot());
682 }
683
684 gig::String StringEntryMultiLine::get_value() const
685 {
686 Glib::ustring value = text_buffer->get_text();
687 for (int i = 0 ; (i = value.find("\x0a", i)) >= 0 ; i += 2)
688 value.replace(i, 1, "\x0d\x0a");
689 return gig_from_utf8(value);
690 }
691
692 void StringEntryMultiLine::set_value(const gig::String& value)
693 {
694 Glib::ustring text = gig_to_utf8(value);
695 for (int i = 0 ; (i = text.find("\x0d\x0a", i, 2)) >= 0 ; i++)
696 text.replace(i, 2, "\x0a");
697 text_buffer->set_text(text);
698 }
699
700 void StringEntryMultiLine::on_show_tooltips_changed() {
701 LabelWidget::on_show_tooltips_changed();
702
703 const bool b = Settings::singleton()->showTooltips;
704 text_view.set_has_tooltip(b);
705 }
706
707
708 Table::Table(int x, int y) :
709 #if USE_GTKMM_GRID
710 Gtk::Grid(),
711 cols(x),
712 #else
713 Gtk::Table(x, y),
714 #endif
715 rowno(0)
716 {
717 }
718
719 void Table::add(BoolEntry& boolentry)
720 {
721 #if USE_GTKMM_GRID
722 attach(boolentry.widget, 0, rowno, 2);
723 #else
724 attach(boolentry.widget, 0, 2, rowno, rowno + 1,
725 Gtk::FILL, Gtk::SHRINK);
726 #endif
727 rowno++;
728 }
729
730 void Table::add(BoolEntryPlus6& boolentry)
731 {
732 #if USE_GTKMM_GRID
733 attach(boolentry.widget, 0, rowno, 2);
734 #else
735 attach(boolentry.widget, 0, 2, rowno, rowno + 1,
736 Gtk::FILL, Gtk::SHRINK);
737 #endif
738 rowno++;
739 }
740
741 void Table::add(LabelWidget& prop)
742 {
743 #if USE_GTKMM_GRID
744 attach(prop.label, 1, rowno);
745 attach(prop.widget, 2, rowno);
746 #else
747 attach(prop.label, 1, 2, rowno, rowno + 1,
748 Gtk::FILL, Gtk::SHRINK);
749 attach(prop.widget, 2, 3, rowno, rowno + 1,
750 Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK);
751 #endif
752 rowno++;
753 }

  ViewVC Help
Powered by ViewVC