/[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 3460 - (hide annotations) (download)
Sat Feb 2 07:48:50 2019 UTC (5 years, 2 months ago) by persson
File size: 20030 byte(s)
* Use GDK Seat API if available to grab pointer
* Improve version checks for pangomm
* Fix the instrument list tooltip handling so it doesn't generate GTK
  assertion error messages
* Use English quotation marks in tooltips instead of German
* Use multiple columns in controller value popups, as tall popup menus
  work really badly in some GTK environments

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     }
141    
142 schoenebeck 2541 #define controlChangeTextsSize (sizeof(controlChangeTexts) / sizeof(CCText))
143 schoenebeck 2538
144 schoenebeck 1225 LabelWidget::LabelWidget(const char* labelText, Gtk::Widget& widget) :
145     label(Glib::ustring(labelText) + ":"),
146     widget(widget)
147     {
148 schoenebeck 3364 #if HAS_GTKMM_ALIGNMENT
149 persson 2169 label.set_alignment(Gtk::ALIGN_START);
150 schoenebeck 3364 #else
151     label.set_halign(Gtk::Align::START);
152     #endif
153 schoenebeck 3409 Settings::singleton()->showTooltips.get_proxy().signal_changed().connect(
154     sigc::mem_fun(this, &LabelWidget::on_show_tooltips_changed)
155     );
156    
157     // workaround for a crash with certain gtkmm versions: postpone calling
158     // on_show_tooltips_changed() because widget.gobj() might be uninitialized
159     // at this point yet
160     Glib::signal_idle().connect_once( // timeout starts given amount of ms after the main loop became idle again ...
161     sigc::mem_fun(*this, &LabelWidget::on_show_tooltips_changed),
162     300
163     );
164 schoenebeck 1225 }
165    
166 schoenebeck 3409 void LabelWidget::on_show_tooltips_changed() {
167     const bool b = Settings::singleton()->showTooltips;
168     label.set_has_tooltip(b);
169     widget.set_has_tooltip(b);
170     }
171    
172 schoenebeck 1225 void LabelWidget::set_sensitive(bool sensitive)
173     {
174     label.set_sensitive(sensitive);
175     widget.set_sensitive(sensitive);
176     }
177    
178 schoenebeck 2690 ReadOnlyLabelWidget::ReadOnlyLabelWidget(const char* leftHandText)
179     : LabelWidget(leftHandText, text)
180     {
181 schoenebeck 3364 #if HAS_GTKMM_ALIGNMENT
182 schoenebeck 2690 text.set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_START);
183 schoenebeck 3364 #else
184     label.set_halign(Gtk::Align::START);
185     label.set_valign(Gtk::Align::START);
186     #endif
187 schoenebeck 2690 }
188    
189     ReadOnlyLabelWidget::ReadOnlyLabelWidget(const char* leftHandText, const char* rightHandText)
190     : LabelWidget(leftHandText, text)
191     {
192 schoenebeck 3364 #if HAS_GTKMM_ALIGNMENT
193 schoenebeck 2690 text.set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_START);
194 schoenebeck 3364 #else
195     text.set_halign(Gtk::Align::START);
196     text.set_valign(Gtk::Align::START);
197     #endif
198 schoenebeck 2690 text.set_text(rightHandText);
199     }
200    
201 schoenebeck 1225 NumEntry::NumEntry(const char* labelText, double lower, double upper,
202     int decimals) :
203 persson 2151 LabelWidget(labelText, box),
204 persson 2169 #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2
205 schoenebeck 1225 adjust(lower, lower, upper, 1, 10),
206 persson 2169 #else
207     adjust(Gtk::Adjustment::create(lower, lower, upper, 1, 10)),
208     #endif
209 schoenebeck 1225 scale(adjust),
210 persson 2151 spinbutton(adjust)
211 schoenebeck 1225 {
212 persson 2423 scale.set_size_request(70);
213 schoenebeck 1225 spinbutton.set_digits(decimals);
214 persson 1460 spinbutton.set_value(0);
215 persson 2507 spinbutton.set_numeric();
216 schoenebeck 1225 scale.set_draw_value(false);
217     box.pack_start(spinbutton, Gtk::PACK_SHRINK);
218     box.add(scale);
219     }
220    
221 schoenebeck 3409 void NumEntry::on_show_tooltips_changed() {
222     LabelWidget::on_show_tooltips_changed();
223    
224     const bool b = Settings::singleton()->showTooltips;
225     spinbutton.set_has_tooltip(b);
226     scale.set_has_tooltip(b);
227     }
228    
229 schoenebeck 1225 NumEntryGain::NumEntryGain(const char* labelText,
230     double lower, double upper,
231     int decimals, double coeff) :
232     NumEntry(labelText, lower, upper, decimals),
233 persson 2151 value(0),
234 persson 1460 coeff(coeff),
235     connected(true)
236 schoenebeck 1225 {
237     spinbutton.signal_value_changed().connect(
238     sigc::mem_fun(*this, &NumEntryGain::value_changed));
239     }
240    
241     void NumEntryGain::value_changed()
242     {
243 persson 1460 if (!connected) return;
244    
245 schoenebeck 1359 const double f = pow(10, spinbutton.get_digits());
246     int new_value = round_to_int(spinbutton.get_value() * f);
247 persson 1460 if (new_value != round_to_int(value / coeff * f)) {
248     value = round_to_int(new_value / f * coeff);
249     sig_changed();
250 schoenebeck 1225 }
251     }
252    
253 persson 1460 void NumEntryGain::set_value(int32_t value)
254 schoenebeck 1225 {
255 persson 1460 if (value != this->value) {
256     this->value = value;
257    
258     connected = false;
259     bool plus6 = value < 0;
260     spinbutton.set_value(plus6 ? 0 : value / coeff);
261     set_sensitive(!plus6);
262     connected = true;
263    
264     sig_changed();
265     }
266 schoenebeck 1225 }
267    
268    
269     BoolEntryPlus6::BoolEntryPlus6(const char* labelText, NumEntryGain& eGain, int32_t plus6value) :
270     LabelWidget(labelText, checkbutton),
271 persson 1262 checkbutton(labelText),
272 schoenebeck 1225 eGain(eGain),
273     plus6value(plus6value)
274     {
275     checkbutton.signal_toggled().connect(
276     sigc::mem_fun(*this, &BoolEntryPlus6::value_changed));
277     }
278    
279 schoenebeck 3409 void BoolEntryPlus6::on_show_tooltips_changed() {
280     LabelWidget::on_show_tooltips_changed();
281    
282     eGain.on_show_tooltips_changed();
283     }
284    
285 schoenebeck 1225 void BoolEntryPlus6::value_changed()
286     {
287 persson 1460 if (checkbutton.get_active()) eGain.set_value(plus6value);
288     else if (eGain.get_value() < 0) eGain.set_value(0);
289 schoenebeck 1225 }
290    
291 persson 1460 int32_t BoolEntryPlus6::get_value() const
292 schoenebeck 1225 {
293 persson 1460 return eGain.get_value();
294 schoenebeck 1225 }
295    
296 persson 1460 void BoolEntryPlus6::set_value(int32_t value)
297     {
298     checkbutton.set_active(value < 0);
299     }
300    
301 schoenebeck 1225 NumEntryPermille::NumEntryPermille(const char* labelText,
302     double lower, double upper, int decimals) :
303 persson 1460 NumEntry(labelText, lower, upper, decimals),
304     value(0)
305 schoenebeck 1225 {
306     spinbutton.signal_value_changed().connect(
307     sigc::mem_fun(*this, &NumEntryPermille::value_changed));
308     }
309    
310     void NumEntryPermille::value_changed()
311     {
312 persson 1460 uint16_t new_value = uint16_t(spinbutton.get_value() * 10 + 0.5);
313     if (new_value != value) {
314     value = uint16_t(spinbutton.get_value() * 10 + 0.5);
315     sig_changed();
316 schoenebeck 1225 }
317     }
318    
319 persson 1460 void NumEntryPermille::set_value(uint16_t value)
320 schoenebeck 1225 {
321 persson 1460 if (value != this->value) {
322     spinbutton.set_value(value / 10.0);
323     }
324 schoenebeck 1225 }
325    
326    
327     NoteEntry::NoteEntry(const char* labelText) :
328     NumEntryTemp<uint8_t>(labelText)
329     {
330 persson 2507 spin_button_show_notes(spinbutton);
331 schoenebeck 1225 }
332    
333 persson 2507 namespace {
334     const char* notes[] = {
335     _("C"), _("C#"), _("D"), _("D#"), _("E"), _("F"),_("F#"),
336     _("G"), _("G#"), _("A"), _("A#"), _("B")
337     };
338 schoenebeck 1225
339 persson 2507 int note_value(const Glib::ustring& note, double* value)
340     {
341     const char* str = note.c_str();
342 schoenebeck 1225
343 persson 2507 int i;
344     for (i = 11 ; i >= 0 ; i--) {
345     if (strncasecmp(str, notes[i], strlen(notes[i])) == 0) break;
346     }
347     if (i >= 0) {
348     char* endptr;
349     long x = strtol(str + strlen(notes[i]), &endptr, 10);
350     if (endptr != str + strlen(notes[i])) {
351     *value = std::max(0L, std::min(i + (x + 1) * 12, 127L));
352     return true;
353     }
354     } else {
355     char* endptr;
356     long x = strtol(str, &endptr, 10);
357     if (endptr != str) {
358     *value = std::max(0L, std::min(x, 127L));
359     return true;
360     }
361     }
362 schoenebeck 3364
363     #if HAS_GTKMM_CPP11_ENUMS
364     return Gtk::SpinButton::INPUT_ERROR;
365     #else
366 persson 2507 return Gtk::INPUT_ERROR;
367 schoenebeck 3364 #endif
368 persson 2507 }
369     }
370    
371     int note_value(const Glib::ustring& note)
372 schoenebeck 1225 {
373 persson 2507 double value = 0;
374     note_value(note, &value);
375     return value;
376     }
377 schoenebeck 1225
378 persson 2507 Glib::ustring note_str(int note)
379     {
380     char buf[10];
381     sprintf(buf, "%s%d", notes[note % 12], note / 12 - 1);
382     return buf;
383     }
384    
385     namespace {
386     // Convert the Entry text to a number
387 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
388     int on_input(double& new_value, Gtk::SpinButton* spinbutton) {
389     return note_value(spinbutton->get_text(), &new_value);
390     }
391     #else
392 persson 2507 int on_input(double* new_value, Gtk::SpinButton* spinbutton) {
393     return note_value(spinbutton->get_text(), new_value);
394 schoenebeck 1225 }
395 schoenebeck 3364 #endif
396 persson 2507
397     // Convert the Adjustment position to text
398     bool on_output(Gtk::SpinButton* spinbutton) {
399     spinbutton->set_text(
400     note_str(spinbutton->get_adjustment()->get_value() + 0.5));
401     return true;
402 schoenebeck 1225 }
403     }
404    
405 persson 2507 // Make a SpinButton show notes instead of numbers
406     void spin_button_show_notes(Gtk::SpinButton& spin_button)
407 schoenebeck 1225 {
408 persson 2507 spin_button.set_numeric(false);
409     spin_button.set_width_chars(4);
410     spin_button.signal_input().connect(
411     sigc::bind(sigc::ptr_fun(&on_input), &spin_button));
412     spin_button.signal_output().connect(
413     sigc::bind(sigc::ptr_fun(&on_output), &spin_button));
414 schoenebeck 1225 }
415    
416 schoenebeck 3409 void ChoiceEntryBase::on_show_tooltips_changed() {
417     LabelWidget::on_show_tooltips_changed();
418    
419     const bool b = Settings::singleton()->showTooltips;
420     combobox.set_has_tooltip(b);
421     }
422    
423 schoenebeck 1225 ChoiceEntryLeverageCtrl::ChoiceEntryLeverageCtrl(const char* labelText) :
424 schoenebeck 3364 #if HAS_GTKMM_ALIGNMENT
425 persson 2151 LabelWidget(labelText, align),
426     align(0, 0, 0, 0)
427 schoenebeck 3364 #else
428     LabelWidget(labelText, combobox)
429     #endif
430 schoenebeck 1225 {
431 schoenebeck 2538 for (int i = 0 ; i < controlChangeTextsSize ; i++) {
432 schoenebeck 2541 if (controlChangeTexts[i].txt) {
433 schoenebeck 2538 const int cc = i - 3;
434     Glib::ustring s = (i < 3)
435 schoenebeck 2541 ? controlChangeTexts[i].txt
436     : Glib::ustring::compose("CC%1: %2%3", cc, controlChangeTexts[i].txt, controlChangeTexts[i].isExtension ? " [EXT]" : "");
437 persson 2507 #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 24) || GTKMM_MAJOR_VERSION < 2
438 schoenebeck 2538 combobox.append_text(s);
439 persson 2169 #else
440 schoenebeck 2538 combobox.append(s);
441 persson 2169 #endif
442 schoenebeck 1225 }
443     }
444 persson 3460 combobox.set_wrap_width(4);
445 schoenebeck 1225 combobox.signal_changed().connect(
446     sigc::mem_fun(*this, &ChoiceEntryLeverageCtrl::value_changed));
447 schoenebeck 3364 #if HAS_GTKMM_ALIGNMENT
448 schoenebeck 1225 align.add(combobox);
449 schoenebeck 3364 #else
450     combobox.set_halign(Gtk::Align::FILL);
451     combobox.set_valign(Gtk::Align::FILL);
452     #endif
453 persson 1460 value.type = gig::leverage_ctrl_t::type_none;
454     value.controller_number = 0;
455 schoenebeck 1225 }
456    
457 schoenebeck 3409 void ChoiceEntryLeverageCtrl::on_show_tooltips_changed() {
458     LabelWidget::on_show_tooltips_changed();
459    
460     const bool b = Settings::singleton()->showTooltips;
461     combobox.set_has_tooltip(b);
462     }
463    
464 schoenebeck 1225 void ChoiceEntryLeverageCtrl::value_changed()
465     {
466 persson 1460 int rowno = combobox.get_active_row_number();
467     switch (rowno)
468     {
469     case -1:
470     break;
471     case 0:
472     value.type = gig::leverage_ctrl_t::type_none;
473     break;
474     case 1:
475     value.type = gig::leverage_ctrl_t::type_channelaftertouch;
476     break;
477     case 2:
478     value.type = gig::leverage_ctrl_t::type_velocity;
479     break;
480     default:
481     value.type = gig::leverage_ctrl_t::type_controlchange;
482     int x = 3;
483 schoenebeck 2538 for (uint cc = 0 ; cc < controlChangeTextsSize - 3 ; cc++) {
484 schoenebeck 2541 if (controlChangeTexts[cc + 3].txt) {
485 persson 1460 if (rowno == x) {
486     value.controller_number = cc;
487 schoenebeck 2541 if (controlChangeTexts[cc + 3].isExtension &&
488     Settings::singleton()->warnUserOnExtensions)
489     {
490     Glib::ustring txt = _("<b>Format Extension</b>\n\nAll controllers 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.)");
491     Gtk::MessageDialog msg(
492     txt, true, Gtk::MESSAGE_WARNING
493     );
494     msg.run();
495     }
496 persson 1460 break;
497 schoenebeck 1225 }
498 persson 1460 x++;
499 schoenebeck 1225 }
500     }
501 persson 1460 break;
502 schoenebeck 1225 }
503 persson 1460 if (rowno >= 0) sig_changed();
504 schoenebeck 1225 }
505    
506 persson 1460 void ChoiceEntryLeverageCtrl::set_value(gig::leverage_ctrl_t value)
507 schoenebeck 1225 {
508 schoenebeck 2538 int comboIndex;
509 persson 1460 switch (value.type)
510 schoenebeck 1225 {
511     case gig::leverage_ctrl_t::type_none:
512 schoenebeck 2538 comboIndex = 0;
513 schoenebeck 1225 break;
514     case gig::leverage_ctrl_t::type_channelaftertouch:
515 schoenebeck 2538 comboIndex = 1;
516 schoenebeck 1225 break;
517     case gig::leverage_ctrl_t::type_velocity:
518 schoenebeck 2538 comboIndex = 2;
519 schoenebeck 1225 break;
520 schoenebeck 2538 case gig::leverage_ctrl_t::type_controlchange: {
521     comboIndex = -1;
522     int x = 3;
523     for (uint cc = 0 ; cc < controlChangeTextsSize - 3 ; cc++) {
524 schoenebeck 2541 if (controlChangeTexts[cc + 3].txt) {
525 persson 1460 if (value.controller_number == cc) {
526 schoenebeck 2538 comboIndex = x;
527 schoenebeck 1225 break;
528     }
529 schoenebeck 2538 x++;
530 schoenebeck 1225 }
531     }
532     break;
533 schoenebeck 2538 }
534 schoenebeck 1225 default:
535 schoenebeck 2538 comboIndex = -1;
536 schoenebeck 1225 break;
537     }
538 schoenebeck 2538 combobox.set_active(comboIndex);
539 schoenebeck 1225 }
540    
541    
542 schoenebeck 3409 BoolBox::BoolBox(const char* labelText) : Gtk::CheckButton(labelText) {
543     signal_toggled().connect(sig_changed.make_slot());
544     Settings::singleton()->showTooltips.get_proxy().signal_changed().connect(
545     sigc::mem_fun(this, &BoolBox::on_show_tooltips_changed)
546     );
547     on_show_tooltips_changed();
548     }
549    
550     void BoolBox::on_show_tooltips_changed() {
551     const bool b = Settings::singleton()->showTooltips;
552     set_has_tooltip(b);
553     }
554    
555    
556 schoenebeck 1225 BoolEntry::BoolEntry(const char* labelText) :
557     LabelWidget(labelText, checkbutton),
558 persson 1460 checkbutton(labelText)
559 schoenebeck 1225 {
560 persson 1460 checkbutton.signal_toggled().connect(sig_changed.make_slot());
561 schoenebeck 1225 }
562    
563    
564     StringEntry::StringEntry(const char* labelText) :
565     LabelWidget(labelText, entry)
566     {
567 persson 1582 entry.signal_changed().connect(sig_changed.make_slot());
568 schoenebeck 1225 }
569    
570 persson 2446 gig::String StringEntry::get_value() const
571     {
572     return gig_from_utf8(entry.get_text());
573     }
574    
575     void StringEntry::set_value(const gig::String& value) {
576     entry.set_text(gig_to_utf8(value));
577     }
578    
579    
580 persson 1582 StringEntryMultiLine::StringEntryMultiLine(const char* labelText) :
581     LabelWidget(labelText, frame)
582 schoenebeck 1225 {
583 persson 1582 text_buffer = text_view.get_buffer();
584     frame.set_shadow_type(Gtk::SHADOW_IN);
585     frame.add(text_view);
586     text_buffer->signal_changed().connect(sig_changed.make_slot());
587 schoenebeck 1225 }
588    
589 persson 1582 gig::String StringEntryMultiLine::get_value() const
590 schoenebeck 1225 {
591 persson 1582 Glib::ustring value = text_buffer->get_text();
592     for (int i = 0 ; (i = value.find("\x0a", i)) >= 0 ; i += 2)
593     value.replace(i, 1, "\x0d\x0a");
594 persson 2446 return gig_from_utf8(value);
595 schoenebeck 1225 }
596 persson 1582
597 persson 2446 void StringEntryMultiLine::set_value(const gig::String& value)
598 persson 1582 {
599 persson 2446 Glib::ustring text = gig_to_utf8(value);
600     for (int i = 0 ; (i = text.find("\x0d\x0a", i, 2)) >= 0 ; i++)
601     text.replace(i, 2, "\x0a");
602     text_buffer->set_text(text);
603 persson 1582 }
604 persson 2423
605 schoenebeck 3409 void StringEntryMultiLine::on_show_tooltips_changed() {
606     LabelWidget::on_show_tooltips_changed();
607 persson 2423
608 schoenebeck 3409 const bool b = Settings::singleton()->showTooltips;
609     text_view.set_has_tooltip(b);
610     }
611    
612    
613 schoenebeck 3364 Table::Table(int x, int y) :
614     #if USE_GTKMM_GRID
615     Gtk::Grid(),
616     cols(x),
617     #else
618     Gtk::Table(x, y),
619     #endif
620     rowno(0)
621     {
622     }
623 persson 2423
624     void Table::add(BoolEntry& boolentry)
625     {
626 schoenebeck 3364 #if USE_GTKMM_GRID
627     attach(boolentry.widget, 0, rowno, 2);
628     #else
629 persson 2423 attach(boolentry.widget, 0, 2, rowno, rowno + 1,
630     Gtk::FILL, Gtk::SHRINK);
631 schoenebeck 3364 #endif
632 persson 2423 rowno++;
633     }
634    
635     void Table::add(BoolEntryPlus6& boolentry)
636     {
637 schoenebeck 3364 #if USE_GTKMM_GRID
638     attach(boolentry.widget, 0, rowno, 2);
639     #else
640 persson 2423 attach(boolentry.widget, 0, 2, rowno, rowno + 1,
641     Gtk::FILL, Gtk::SHRINK);
642 schoenebeck 3364 #endif
643 persson 2423 rowno++;
644     }
645    
646     void Table::add(LabelWidget& prop)
647     {
648 schoenebeck 3364 #if USE_GTKMM_GRID
649     attach(prop.label, 1, rowno);
650     attach(prop.widget, 2, rowno);
651     #else
652 persson 2423 attach(prop.label, 1, 2, rowno, rowno + 1,
653     Gtk::FILL, Gtk::SHRINK);
654     attach(prop.widget, 2, 3, rowno, rowno + 1,
655     Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK);
656 schoenebeck 3364 #endif
657 persson 2423 rowno++;
658     }

  ViewVC Help
Powered by ViewVC