2
Copyright (C) 2009 Paul Davis
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.
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.
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.
20
#ifndef __gtk_ardour_option_editor_h__
21
#define __gtk_ardour_option_editor_h__
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"
33
/** @file option_editor.h
34
* @brief Base class for option editing dialog boxes.
36
* Code to provided the basis for dialogs which allow the user to edit options
37
* from an ARDOUR::Configuration class.
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.
45
* It is intended that OptionEditor be subclassed to implement a particular
53
class OptionEditorPage;
55
/** Base class for components of an OptionEditor dialog */
56
class OptionEditorComponent
59
virtual ~OptionEditorComponent() {}
61
/** Called when a configuration parameter's value has changed.
62
* @param p parameter name
64
virtual void parameter_changed (std::string const & p) = 0;
66
/** Called to instruct the object to set its UI state from the configuration */
67
virtual void set_state_from_config () = 0;
69
/** Called to instruct the object to add itself to an OptionEditorPage */
70
virtual void add_to_page (OptionEditorPage *) = 0;
72
void add_widget_to_page (OptionEditorPage*, Gtk::Widget*);
73
void add_widgets_to_page (OptionEditorPage*, Gtk::Widget*, Gtk::Widget*);
75
void set_note (std::string const &);
77
virtual Gtk::Widget& tip_widget() = 0;
80
void maybe_add_note (OptionEditorPage *, int);
85
/** A component which provides a subheading within the dialog */
86
class OptionEditorHeading : public OptionEditorComponent
89
OptionEditorHeading (std::string const &);
91
void parameter_changed (std::string const &) {}
92
void set_state_from_config () {}
93
void add_to_page (OptionEditorPage *);
95
Gtk::Widget& tip_widget() { return *_label; }
98
Gtk::Label* _label; ///< the label used for the heading
101
/** A component which provides a box into which a subclass can put arbitrary widgets */
102
class OptionEditorBox : public OptionEditorComponent
106
/** Construct an OpenEditorBox */
109
_box = Gtk::manage (new Gtk::VBox);
110
_box->set_spacing (4);
113
void parameter_changed (std::string const &) = 0;
114
void set_state_from_config () = 0;
115
void add_to_page (OptionEditorPage *);
117
Gtk::Widget& tip_widget() { return *_box->children().front().get_widget(); }
121
Gtk::VBox* _box; ///< constituent box for subclasses to add widgets to
124
/** Base class for components which provide UI to change an option */
125
class Option : public OptionEditorComponent
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")
132
Option (std::string const & i,
133
std::string const & n
139
void parameter_changed (std::string const & p)
142
set_state_from_config ();
146
virtual void set_state_from_config () = 0;
147
virtual void add_to_page (OptionEditorPage*) = 0;
149
std::string id () const {
159
/** Component which provides the UI to handle a boolean option using a GTK CheckButton */
160
class BoolOption : public Option
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*);
168
void set_sensitive (bool yn) {
169
_button->set_sensitive (yn);
172
Gtk::Widget& tip_widget() { return *_button; }
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
184
/** Component which provides the UI to handle a string option using a GTK Entry */
185
class EntryOption : public Option
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*);
193
Gtk::Widget& tip_widget() { return *_entry; }
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
206
/** Component which provides the UI to handle an enumerated option using a GTK ComboBox.
207
* The template parameter is the enumeration.
210
class ComboOption : public Option
214
/** Construct an ComboOption.
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.
221
std::string const & i,
222
std::string const & n,
224
sigc::slot<bool, T> s
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));
236
void set_state_from_config () {
238
while (r < _options.size() && _get () != _options[r]) {
242
if (r < _options.size()) {
243
_combo->set_active (r);
247
void add_to_page (OptionEditorPage* p)
249
add_widgets_to_page (p, _label, _combo);
252
/** Add an allowed value for this option.
253
* @param e Enumeration.
254
* @param o User-visible name for this value.
256
void add (T e, std::string const & o) {
257
_options.push_back (e);
258
_combo->append_text (o);
262
_combo->clear_items();
267
uint32_t const r = _combo->get_active_row_number ();
268
if (r < _options.size()) {
273
void set_sensitive (bool yn) {
274
_combo->set_sensitive (yn);
277
Gtk::Widget& tip_widget() { return *_combo; }
282
sigc::slot<bool, T> _set;
284
Gtk::ComboBoxText* _combo;
285
std::vector<T> _options;
289
/** Component which provides the UI for a GTK HScale.
291
class HSliderOption : public Option
295
/** Construct an ComboOption.
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.
302
std::string const & i,
303
std::string const & n,
308
_label = manage (new Gtk::Label (n + ":"));
309
_label->set_alignment (0, 0.5);
310
_hscale = manage (new Gtk::HScale(adj));
315
std::string const & i,
316
std::string const & n,
317
Gtk::Adjustment *adj,
319
sigc::slot<bool, float> s
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));
332
void set_state_from_config () {
333
if (_adj) _adj->set_value (_get());
337
if (_adj) _set (_adj->get_value ());
340
void add_to_page (OptionEditorPage* p)
342
add_widgets_to_page (p, _label, _hscale);
345
void set_sensitive (bool yn) {
346
_hscale->set_sensitive (yn);
349
Gtk::Widget& tip_widget() { return *_hscale; }
352
sigc::slot<float> _get;
353
sigc::slot<bool, float> _set;
355
Gtk::HScale* _hscale;
356
Gtk::Adjustment* _adj;
359
/** Component which provides the UI to handle an enumerated option using a GTK ComboBox.
360
* The template parameter is the enumeration.
362
class ComboStringOption : public Option
366
/** Construct an ComboOption.
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.
373
std::string const & i,
374
std::string const & n,
375
sigc::slot<std::string> g,
376
sigc::slot<bool, std::string> s
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));
388
void set_state_from_config () {
389
_combo->set_active_text (_get());
392
void add_to_page (OptionEditorPage* p)
394
add_widgets_to_page (p, _label, _combo);
397
/** Set the allowed strings for this option
398
* @param strings a vector of allowed strings
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);
408
_combo->clear_items();
412
_set (_combo->get_active_text ());
415
void set_sensitive (bool yn) {
416
_combo->set_sensitive (yn);
419
Gtk::Widget& tip_widget() { return *_combo; }
422
sigc::slot<std::string> _get;
423
sigc::slot<bool, std::string> _set;
425
Gtk::ComboBoxText* _combo;
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.
432
class BoolComboOption : public Option
442
sigc::slot<bool, bool>
445
void set_state_from_config ();
446
void add_to_page (OptionEditorPage *);
448
void set_sensitive (bool);
450
Gtk::Widget& tip_widget() { return *_combo; }
454
sigc::slot<bool> _get;
455
sigc::slot<bool, bool> _set;
457
Gtk::ComboBoxText* _combo;
462
/** Component which provides the UI to handle an numeric option using a GTK SpinButton */
464
class SpinOption : public Option
467
/** Construct an SpinOption.
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)
480
std::string const & i,
481
std::string const & n,
483
sigc::slot<bool, T> s,
488
std::string const & unit = "",
496
_label = manage (new Gtk::Label (n + ":"));
497
_label->set_alignment (0, 0.5);
499
_spin = manage (new Gtk::SpinButton);
500
_spin->set_range (min, max);
501
_spin->set_increments (step, page);
503
_box = manage (new Gtk::HBox);
504
_box->pack_start (*_spin, true, true);
505
_box->set_spacing (4);
507
_box->pack_start (*manage (new Gtk::Label (unit)), false, false);
510
_spin->signal_value_changed().connect (sigc::mem_fun (*this, &SpinOption::changed));
513
void set_state_from_config ()
515
_spin->set_value (_get () / _scale);
518
void add_to_page (OptionEditorPage* p)
520
add_widgets_to_page (p, _label, _box);
525
_set (static_cast<T> (_spin->get_value ()) * _scale);
528
Gtk::Widget& tip_widget() { return *_spin; }
532
sigc::slot<bool, T> _set;
536
Gtk::SpinButton* _spin;
539
class FaderOption : public Option
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 *);
547
Gtk::Widget& tip_widget() { return *_db_slider; }
552
Gtk::Adjustment _db_adjustment;
553
Gtkmm2ext::HSliderController* _db_slider;
554
Gtk::Entry _db_display;
557
Gtk::VBox _fader_centering_box;
558
sigc::slot<ARDOUR::gain_t> _get;
559
sigc::slot<bool, ARDOUR::gain_t> _set;
562
class ClockOption : public Option
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 *);
570
Gtk::Widget& tip_widget() { return _clock; }
571
AudioClock& clock() { return _clock; }
574
void save_clock_time ();
577
sigc::slot<std::string> _get;
578
sigc::slot<bool, std::string> _set;
579
ARDOUR::Session *_session;
582
class DirectoryOption : public Option
585
DirectoryOption (std::string const &, std::string const &, sigc::slot<std::string>, sigc::slot<bool, std::string>);
587
void set_state_from_config ();
588
void add_to_page (OptionEditorPage *);
590
Gtk::Widget& tip_widget() { return _file_chooser; }
594
void current_folder_set ();
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;
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.
605
class OptionEditorPage
608
OptionEditorPage (Gtk::Notebook&, std::string const &);
612
std::list<OptionEditorComponent*> components;
615
/** The OptionEditor dialog base class */
616
class OptionEditor : public ArdourWindow
619
OptionEditor (ARDOUR::Configuration *, std::string const &);
622
void add_option (std::string const &, OptionEditorComponent *);
624
void set_current_page (std::string const &);
628
virtual void parameter_changed (std::string const &);
630
ARDOUR::Configuration* _config;
634
PBD::ScopedConnection config_connection;
636
Gtk::Notebook _notebook;
637
std::map<std::string, OptionEditorPage*> _pages;
640
#endif /* __gtk_ardour_option_editor_h__ */