~ubuntu-branches/ubuntu/utopic/ardour3/utopic

« back to all changes in this revision

Viewing changes to gtk2_ardour/option_editor.h

  • Committer: Package Import Robot
  • Author(s): Felipe Sateler
  • Date: 2013-09-21 19:05:02 UTC
  • Revision ID: package-import@ubuntu.com-20130921190502-8gsftrku6jnzhd7v
Tags: upstream-3.4~dfsg
ImportĀ upstreamĀ versionĀ 3.4~dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
    Copyright (C) 2009 Paul Davis
 
3
 
 
4
    This program is free software; you can redistribute it and/or modify
 
5
    it under the terms of the GNU General Public License as published by
 
6
    the Free Software Foundation; either version 2 of the License, or
 
7
    (at your option) any later version.
 
8
 
 
9
    This program is distributed in the hope that it will be useful,
 
10
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
    GNU General Public License for more details.
 
13
 
 
14
    You should have received a copy of the GNU General Public License
 
15
    along with this program; if not, write to the Free Software
 
16
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
17
 
 
18
*/
 
19
 
 
20
#ifndef __gtk_ardour_option_editor_h__
 
21
#define __gtk_ardour_option_editor_h__
 
22
 
 
23
#include <gtkmm/notebook.h>
 
24
#include <gtkmm/checkbutton.h>
 
25
#include <gtkmm/comboboxtext.h>
 
26
#include <gtkmm/spinbutton.h>
 
27
#include <gtkmm/table.h>
 
28
#include "gtkmm2ext/slider_controller.h"
 
29
#include "ardour_window.h"
 
30
#include "audio_clock.h"
 
31
#include "ardour/types.h"
 
32
 
 
33
/** @file option_editor.h
 
34
 *  @brief Base class for option editing dialog boxes.
 
35
 *
 
36
 *  Code to provided the basis for dialogs which allow the user to edit options
 
37
 *  from an ARDOUR::Configuration class.
 
38
 *
 
39
 *  The idea is that we have an OptionEditor class which is the dialog box.
 
40
 *  This is essentially a GTK Notebook.  OptionEditorComponent objects can
 
41
 *  then be added to the OptionEditor, and these components are arranged on
 
42
 *  the pages of the Notebook.  There is also an OptionEditorComponent hierarchy
 
43
 *  here, providing things like boolean and combobox option components.
 
44
 *
 
45
 *  It is intended that OptionEditor be subclassed to implement a particular
 
46
 *  options dialog.
 
47
 */
 
48
 
 
49
namespace ARDOUR {
 
50
        class Configuration;
 
51
}
 
52
 
 
53
class OptionEditorPage;
 
54
 
 
55
/** Base class for components of an OptionEditor dialog */
 
56
class OptionEditorComponent
 
57
{
 
58
public:
 
59
        virtual ~OptionEditorComponent() {}
 
60
 
 
61
        /** Called when a configuration parameter's value has changed.
 
62
         *  @param p parameter name
 
63
         */
 
64
        virtual void parameter_changed (std::string const & p) = 0;
 
65
 
 
66
        /** Called to instruct the object to set its UI state from the configuration */
 
67
        virtual void set_state_from_config () = 0;
 
68
 
 
69
        /** Called to instruct the object to add itself to an OptionEditorPage */
 
70
        virtual void add_to_page (OptionEditorPage *) = 0;
 
71
 
 
72
        void add_widget_to_page (OptionEditorPage*, Gtk::Widget*);
 
73
        void add_widgets_to_page (OptionEditorPage*, Gtk::Widget*, Gtk::Widget*);
 
74
 
 
75
        void set_note (std::string const &);
 
76
 
 
77
        virtual Gtk::Widget& tip_widget() = 0;
 
78
 
 
79
private:
 
80
        void maybe_add_note (OptionEditorPage *, int);
 
81
        
 
82
        std::string _note;
 
83
};
 
84
 
 
85
/** A component which provides a subheading within the dialog */
 
86
class OptionEditorHeading : public OptionEditorComponent
 
87
{
 
88
public:
 
89
        OptionEditorHeading (std::string const &);
 
90
 
 
91
        void parameter_changed (std::string const &) {}
 
92
        void set_state_from_config () {}
 
93
        void add_to_page (OptionEditorPage *);
 
94
 
 
95
        Gtk::Widget& tip_widget() { return *_label; }
 
96
 
 
97
private:
 
98
        Gtk::Label* _label; ///< the label used for the heading
 
99
};
 
100
 
 
101
/** A component which provides a box into which a subclass can put arbitrary widgets */
 
102
class OptionEditorBox : public OptionEditorComponent
 
103
{
 
104
public:
 
105
 
 
106
        /** Construct an OpenEditorBox */
 
107
        OptionEditorBox ()
 
108
        {
 
109
                _box = Gtk::manage (new Gtk::VBox);
 
110
                _box->set_spacing (4);
 
111
        }
 
112
 
 
113
        void parameter_changed (std::string const &) = 0;
 
114
        void set_state_from_config () = 0;
 
115
        void add_to_page (OptionEditorPage *);
 
116
 
 
117
        Gtk::Widget& tip_widget() { return *_box->children().front().get_widget(); }
 
118
 
 
119
protected:
 
120
 
 
121
        Gtk::VBox* _box; ///< constituent box for subclasses to add widgets to
 
122
};
 
123
 
 
124
/** Base class for components which provide UI to change an option */
 
125
class Option : public OptionEditorComponent
 
126
{
 
127
public:
 
128
        /** Construct an Option.
 
129
         *  @param i Option id (e.g. "plugins-stop-with-transport")
 
130
         *  @param n User-visible name (e.g. "Stop plugins when the transport is stopped")
 
131
         */
 
132
        Option (std::string const & i,
 
133
                std::string const & n
 
134
                )
 
135
                : _id (i),
 
136
                  _name (n)
 
137
        {}
 
138
 
 
139
        void parameter_changed (std::string const & p)
 
140
        {
 
141
                if (p == _id) {
 
142
                        set_state_from_config ();
 
143
                }
 
144
        }
 
145
 
 
146
        virtual void set_state_from_config () = 0;
 
147
        virtual void add_to_page (OptionEditorPage*) = 0;
 
148
 
 
149
        std::string id () const {
 
150
                return _id;
 
151
        }
 
152
 
 
153
protected:
 
154
 
 
155
        std::string _id;
 
156
        std::string _name;
 
157
};
 
158
 
 
159
/** Component which provides the UI to handle a boolean option using a GTK CheckButton */
 
160
class BoolOption : public Option
 
161
{
 
162
public:
 
163
 
 
164
        BoolOption (std::string const &, std::string const &, sigc::slot<bool>, sigc::slot<bool, bool>);
 
165
        void set_state_from_config ();
 
166
        void add_to_page (OptionEditorPage*);
 
167
 
 
168
        void set_sensitive (bool yn) {
 
169
                _button->set_sensitive (yn);
 
170
        }
 
171
 
 
172
        Gtk::Widget& tip_widget() { return *_button; }
 
173
 
 
174
private:
 
175
 
 
176
        void toggled ();
 
177
 
 
178
        sigc::slot<bool>       _get; ///< slot to get the configuration variable's value
 
179
        sigc::slot<bool, bool> _set;  ///< slot to set the configuration variable's value
 
180
        Gtk::CheckButton*      _button; ///< UI button
 
181
        Gtk::Label*            _label; ///< label for button, so we can use markup
 
182
};
 
183
 
 
184
/** Component which provides the UI to handle a string option using a GTK Entry */
 
185
class EntryOption : public Option
 
186
{
 
187
public:
 
188
 
 
189
        EntryOption (std::string const &, std::string const &, sigc::slot<std::string>, sigc::slot<bool, std::string>);
 
190
        void set_state_from_config ();
 
191
        void add_to_page (OptionEditorPage*);
 
192
 
 
193
        Gtk::Widget& tip_widget() { return *_entry; }
 
194
 
 
195
private:
 
196
 
 
197
        void activated ();
 
198
 
 
199
        sigc::slot<std::string> _get; ///< slot to get the configuration variable's value
 
200
        sigc::slot<bool, std::string> _set;  ///< slot to set the configuration variable's value
 
201
        Gtk::Label* _label; ///< UI label
 
202
        Gtk::Entry* _entry; ///< UI entry
 
203
};
 
204
 
 
205
 
 
206
/** Component which provides the UI to handle an enumerated option using a GTK ComboBox.
 
207
 *  The template parameter is the enumeration.
 
208
 */
 
209
template <class T>
 
210
class ComboOption : public Option
 
211
{
 
212
public:
 
213
 
 
214
        /** Construct an ComboOption.
 
215
         *  @param i id
 
216
         *  @param n User-visible name.
 
217
         *  @param g Slot to get the variable's value.
 
218
         *  @param s Slot to set the variable's value.
 
219
         */
 
220
        ComboOption (
 
221
                std::string const & i,
 
222
                std::string const & n,
 
223
                sigc::slot<T> g,
 
224
                sigc::slot<bool, T> s
 
225
                )
 
226
                : Option (i, n),
 
227
                  _get (g),
 
228
                  _set (s)
 
229
        {
 
230
                _label = manage (new Gtk::Label (n + ":"));
 
231
                _label->set_alignment (0, 0.5);
 
232
                _combo = manage (new Gtk::ComboBoxText);
 
233
                _combo->signal_changed().connect (sigc::mem_fun (*this, &ComboOption::changed));
 
234
        }
 
235
 
 
236
        void set_state_from_config () {
 
237
                uint32_t r = 0;
 
238
                while (r < _options.size() && _get () != _options[r]) {
 
239
                        ++r;
 
240
                }
 
241
 
 
242
                if (r < _options.size()) {
 
243
                        _combo->set_active (r);
 
244
                }
 
245
        }
 
246
 
 
247
        void add_to_page (OptionEditorPage* p)
 
248
        {
 
249
                add_widgets_to_page (p, _label, _combo);
 
250
        }
 
251
 
 
252
        /** Add an allowed value for this option.
 
253
         *  @param e Enumeration.
 
254
         *  @param o User-visible name for this value.
 
255
         */
 
256
        void add (T e, std::string const & o) {
 
257
                _options.push_back (e);
 
258
                _combo->append_text (o);
 
259
        }
 
260
 
 
261
        void clear () {
 
262
                _combo->clear_items();
 
263
                _options.clear ();
 
264
        }
 
265
 
 
266
        void changed () {
 
267
                uint32_t const r = _combo->get_active_row_number ();
 
268
                if (r < _options.size()) {
 
269
                        _set (_options[r]);
 
270
                }
 
271
        }
 
272
 
 
273
        void set_sensitive (bool yn) {
 
274
                _combo->set_sensitive (yn);
 
275
        }
 
276
 
 
277
        Gtk::Widget& tip_widget() { return *_combo; }
 
278
 
 
279
private:
 
280
 
 
281
        sigc::slot<T> _get;
 
282
        sigc::slot<bool, T> _set;
 
283
        Gtk::Label* _label;
 
284
        Gtk::ComboBoxText* _combo;
 
285
        std::vector<T> _options;
 
286
};
 
287
 
 
288
 
 
289
/** Component which provides the UI for a GTK HScale.
 
290
 */
 
291
class HSliderOption : public Option
 
292
{
 
293
public:
 
294
 
 
295
        /** Construct an ComboOption.
 
296
         *  @param i id
 
297
         *  @param n User-visible name.
 
298
         *  @param g Slot to get the variable's value.
 
299
         *  @param s Slot to set the variable's value.
 
300
         */
 
301
        HSliderOption (
 
302
                std::string const & i,
 
303
                std::string const & n,
 
304
                Gtk::Adjustment &adj
 
305
                )
 
306
                : Option (i, n)
 
307
        {
 
308
                _label = manage (new Gtk::Label (n + ":"));
 
309
                _label->set_alignment (0, 0.5);
 
310
                _hscale = manage (new Gtk::HScale(adj));
 
311
                _adj = NULL;
 
312
        }
 
313
 
 
314
        HSliderOption (
 
315
                std::string const & i,
 
316
                std::string const & n,
 
317
                Gtk::Adjustment *adj,
 
318
                sigc::slot<float> g,
 
319
                sigc::slot<bool, float> s
 
320
                )
 
321
                : Option (i, n)
 
322
                , _get (g)
 
323
                , _set (s)
 
324
                , _adj (adj)
 
325
        {
 
326
                _label = manage (new Gtk::Label (n + ":"));
 
327
                _label->set_alignment (0, 0.5);
 
328
                _hscale = manage (new Gtk::HScale(*_adj));
 
329
                _adj->signal_value_changed().connect (sigc::mem_fun (*this, &HSliderOption::changed));
 
330
        }
 
331
 
 
332
        void set_state_from_config () {
 
333
                if (_adj) _adj->set_value (_get());
 
334
        }
 
335
 
 
336
        void changed () {
 
337
                if (_adj) _set (_adj->get_value ());
 
338
        }
 
339
 
 
340
        void add_to_page (OptionEditorPage* p)
 
341
        {
 
342
                add_widgets_to_page (p, _label, _hscale);
 
343
        }
 
344
 
 
345
        void set_sensitive (bool yn) {
 
346
                _hscale->set_sensitive (yn);
 
347
        }
 
348
 
 
349
        Gtk::Widget& tip_widget() { return *_hscale; }
 
350
 
 
351
private:
 
352
        sigc::slot<float> _get;
 
353
        sigc::slot<bool, float> _set;
 
354
        Gtk::Label* _label;
 
355
        Gtk::HScale* _hscale;
 
356
        Gtk::Adjustment* _adj;
 
357
};
 
358
 
 
359
/** Component which provides the UI to handle an enumerated option using a GTK ComboBox.
 
360
 *  The template parameter is the enumeration.
 
361
 */
 
362
class ComboStringOption : public Option
 
363
{
 
364
public:
 
365
 
 
366
        /** Construct an ComboOption.
 
367
         *  @param i id
 
368
         *  @param n User-visible name.
 
369
         *  @param g Slot to get the variable's value.
 
370
         *  @param s Slot to set the variable's value.
 
371
         */
 
372
        ComboStringOption (
 
373
                std::string const & i,
 
374
                std::string const & n,
 
375
                sigc::slot<std::string> g,
 
376
                sigc::slot<bool, std::string> s
 
377
                )
 
378
                : Option (i, n),
 
379
                  _get (g),
 
380
                  _set (s)
 
381
        {
 
382
                _label = manage (new Gtk::Label (n + ":"));
 
383
                _label->set_alignment (0, 0.5);
 
384
                _combo = manage (new Gtk::ComboBoxText);
 
385
                _combo->signal_changed().connect (sigc::mem_fun (*this, &ComboStringOption::changed));
 
386
        }
 
387
 
 
388
        void set_state_from_config () {
 
389
                _combo->set_active_text (_get());
 
390
        }
 
391
 
 
392
        void add_to_page (OptionEditorPage* p)
 
393
        {
 
394
                add_widgets_to_page (p, _label, _combo);
 
395
        }
 
396
 
 
397
        /** Set the allowed strings for this option
 
398
         *  @param strings a vector of allowed strings
 
399
         */
 
400
        void set_popdown_strings (const std::vector<std::string>& strings) {
 
401
                _combo->clear_items ();
 
402
                for (std::vector<std::string>::const_iterator i = strings.begin(); i != strings.end(); ++i) {
 
403
                        _combo->append_text (*i);
 
404
                }
 
405
        }
 
406
 
 
407
        void clear () {
 
408
                _combo->clear_items();
 
409
        }
 
410
 
 
411
        void changed () {
 
412
                _set (_combo->get_active_text ());
 
413
        }
 
414
 
 
415
        void set_sensitive (bool yn) {
 
416
                _combo->set_sensitive (yn);
 
417
        }
 
418
 
 
419
        Gtk::Widget& tip_widget() { return *_combo; }
 
420
 
 
421
private:
 
422
        sigc::slot<std::string> _get;
 
423
        sigc::slot<bool, std::string> _set;
 
424
        Gtk::Label* _label;
 
425
        Gtk::ComboBoxText* _combo;
 
426
};
 
427
 
 
428
 
 
429
/** Component which provides the UI to handle a boolean option which needs
 
430
 *  to be represented as a ComboBox to be clear to the user.
 
431
 */
 
432
class BoolComboOption : public Option
 
433
{
 
434
public:
 
435
 
 
436
        BoolComboOption (
 
437
                std::string const &,
 
438
                std::string const &,
 
439
                std::string const &,
 
440
                std::string const &,
 
441
                sigc::slot<bool>,
 
442
                sigc::slot<bool, bool>
 
443
                );
 
444
 
 
445
        void set_state_from_config ();
 
446
        void add_to_page (OptionEditorPage *);
 
447
        void changed ();
 
448
        void set_sensitive (bool);
 
449
 
 
450
        Gtk::Widget& tip_widget() { return *_combo; }
 
451
 
 
452
private:
 
453
 
 
454
        sigc::slot<bool> _get;
 
455
        sigc::slot<bool, bool> _set;
 
456
        Gtk::Label* _label;
 
457
        Gtk::ComboBoxText* _combo;
 
458
};
 
459
 
 
460
 
 
461
 
 
462
/** Component which provides the UI to handle an numeric option using a GTK SpinButton */
 
463
template <class T>
 
464
class SpinOption : public Option
 
465
{
 
466
public:
 
467
        /** Construct an SpinOption.
 
468
         *  @param i id
 
469
         *  @param n User-visible name.
 
470
         *  @param g Slot to get the variable's value.
 
471
         *  @param s Slot to set the variable's value.
 
472
         *  @param min Variable minimum value.
 
473
         *  @param max Variable maximum value.
 
474
         *  @param step Step for the spin button.
 
475
         *  @param page Page step for the spin button.
 
476
         *  @param unit Unit name.
 
477
         *  @param scale Scaling factor (such that for a value x in the spinbutton, x * scale is written to the config)
 
478
         */
 
479
        SpinOption (
 
480
                std::string const & i,
 
481
                std::string const & n,
 
482
                sigc::slot<T> g,
 
483
                sigc::slot<bool, T> s,
 
484
                T min,
 
485
                T max,
 
486
                T step,
 
487
                T page,
 
488
                std::string const & unit = "",
 
489
                float scale = 1
 
490
                )
 
491
                : Option (i, n),
 
492
                  _get (g),
 
493
                  _set (s),
 
494
                  _scale (scale)
 
495
        {
 
496
                _label = manage (new Gtk::Label (n + ":"));
 
497
                _label->set_alignment (0, 0.5);
 
498
 
 
499
                _spin = manage (new Gtk::SpinButton);
 
500
                _spin->set_range (min, max);
 
501
                _spin->set_increments (step, page);
 
502
 
 
503
                _box = manage (new Gtk::HBox);
 
504
                _box->pack_start (*_spin, true, true);
 
505
                _box->set_spacing (4);
 
506
                if (unit.length()) {
 
507
                        _box->pack_start (*manage (new Gtk::Label (unit)), false, false);
 
508
                }
 
509
 
 
510
                _spin->signal_value_changed().connect (sigc::mem_fun (*this, &SpinOption::changed));
 
511
        }
 
512
 
 
513
        void set_state_from_config ()
 
514
        {
 
515
                _spin->set_value (_get () / _scale);
 
516
        }
 
517
 
 
518
        void add_to_page (OptionEditorPage* p)
 
519
        {
 
520
                add_widgets_to_page (p, _label, _box);
 
521
        }
 
522
 
 
523
        void changed ()
 
524
        {
 
525
                _set (static_cast<T> (_spin->get_value ()) * _scale);
 
526
        }
 
527
 
 
528
        Gtk::Widget& tip_widget() { return *_spin; }
 
529
 
 
530
private:
 
531
        sigc::slot<T> _get;
 
532
        sigc::slot<bool, T> _set;
 
533
        float _scale;
 
534
        Gtk::Label* _label;
 
535
        Gtk::HBox* _box;
 
536
        Gtk::SpinButton* _spin;
 
537
};
 
538
 
 
539
class FaderOption : public Option
 
540
{
 
541
public:
 
542
 
 
543
        FaderOption (std::string const &, std::string const &, sigc::slot<ARDOUR::gain_t> g, sigc::slot<bool, ARDOUR::gain_t> s);
 
544
        void set_state_from_config ();
 
545
        void add_to_page (OptionEditorPage *);
 
546
 
 
547
        Gtk::Widget& tip_widget() { return *_db_slider; }
 
548
 
 
549
private:
 
550
        void db_changed ();
 
551
 
 
552
        Gtk::Adjustment _db_adjustment;
 
553
        Gtkmm2ext::HSliderController* _db_slider;
 
554
        Gtk::Entry _db_display;
 
555
        Gtk::Label _label;
 
556
        Gtk::HBox _box;
 
557
        Gtk::VBox _fader_centering_box;
 
558
        sigc::slot<ARDOUR::gain_t> _get;
 
559
        sigc::slot<bool, ARDOUR::gain_t> _set;
 
560
};
 
561
 
 
562
class ClockOption : public Option
 
563
{
 
564
public:
 
565
        ClockOption (std::string const &, std::string const &, sigc::slot<std::string>, sigc::slot<bool, std::string>);
 
566
        void set_state_from_config ();
 
567
        void add_to_page (OptionEditorPage *);
 
568
        void set_session (ARDOUR::Session *);
 
569
 
 
570
        Gtk::Widget& tip_widget() { return _clock; }
 
571
        AudioClock& clock() { return _clock; }
 
572
 
 
573
private:
 
574
        void save_clock_time ();
 
575
        Gtk::Label _label;
 
576
        AudioClock _clock;
 
577
        sigc::slot<std::string> _get;
 
578
        sigc::slot<bool, std::string> _set;
 
579
        ARDOUR::Session *_session;
 
580
};
 
581
 
 
582
class DirectoryOption : public Option
 
583
{
 
584
public:
 
585
        DirectoryOption (std::string const &, std::string const &, sigc::slot<std::string>, sigc::slot<bool, std::string>);
 
586
 
 
587
        void set_state_from_config ();
 
588
        void add_to_page (OptionEditorPage *);
 
589
 
 
590
        Gtk::Widget& tip_widget() { return _file_chooser; }
 
591
 
 
592
private:
 
593
        void file_set ();
 
594
        void current_folder_set ();
 
595
        
 
596
        sigc::slot<std::string> _get; ///< slot to get the configuration variable's value
 
597
        sigc::slot<bool, std::string> _set;  ///< slot to set the configuration variable's value
 
598
        Gtk::FileChooserButton _file_chooser;
 
599
};
 
600
 
 
601
/** Class to represent a single page in an OptionEditor's notebook.
 
602
 *  Pages are laid out using a 3-column table; the 1st column is used
 
603
 *  to indent non-headings, and the 2nd and 3rd for actual content.
 
604
 */
 
605
class OptionEditorPage
 
606
{
 
607
public:
 
608
        OptionEditorPage (Gtk::Notebook&, std::string const &);
 
609
 
 
610
        Gtk::VBox box;
 
611
        Gtk::Table table;
 
612
        std::list<OptionEditorComponent*> components;
 
613
};
 
614
 
 
615
/** The OptionEditor dialog base class */
 
616
class OptionEditor : public ArdourWindow
 
617
{
 
618
public:
 
619
        OptionEditor (ARDOUR::Configuration *, std::string const &);
 
620
        ~OptionEditor ();
 
621
 
 
622
        void add_option (std::string const &, OptionEditorComponent *);
 
623
 
 
624
        void set_current_page (std::string const &);
 
625
 
 
626
protected:
 
627
 
 
628
        virtual void parameter_changed (std::string const &);
 
629
 
 
630
        ARDOUR::Configuration* _config;
 
631
 
 
632
private:
 
633
 
 
634
        PBD::ScopedConnection config_connection;
 
635
 
 
636
        Gtk::Notebook _notebook;
 
637
        std::map<std::string, OptionEditorPage*> _pages;
 
638
};
 
639
 
 
640
#endif /* __gtk_ardour_option_editor_h__ */
 
641
 
 
642