expose Gtk::HScale member of OptionEditor::HSliderOption
[ardour.git] / gtk2_ardour / option_editor.h
index 77e55dce7a6aea08010258b7945f0f980f4751fe..d98bcb467a31e28d394f2d3622988a3a46b29bcf 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2001 Paul Davis 
+    Copyright (C) 2009 Paul Davis
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -15,7 +15,6 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id$
 */
 
 #ifndef __gtk_ardour_option_editor_h__
 
 #include <gtkmm/notebook.h>
 #include <gtkmm/checkbutton.h>
-#include <gtkmm/table.h>
-#include <gtkmm/entry.h>
-#include <gtkmm/box.h>
-#include <gtkmm/label.h>
-#include <gtkmm/adjustment.h>
-#include <gtkmm/scale.h>
-#include <gtkmm/spinbutton.h>
-#include <gtkmm/radiobutton.h>
 #include <gtkmm/comboboxtext.h>
+#include <gtkmm/spinbutton.h>
+#include <gtkmm/table.h>
+#include "gtkmm2ext/slider_controller.h"
+#include "ardour_window.h"
+#include "audio_clock.h"
+#include "ardour/types.h"
+
+/** @file option_editor.h
+ *  @brief Base class for option editing dialog boxes.
+ *
+ *  Code to provided the basis for dialogs which allow the user to edit options
+ *  from an ARDOUR::Configuration class.
+ *
+ *  The idea is that we have an OptionEditor class which is the dialog box.
+ *  This is essentially a GTK Notebook.  OptionEditorComponent objects can
+ *  then be added to the OptionEditor, and these components are arranged on
+ *  the pages of the Notebook.  There is also an OptionEditorComponent hierarchy
+ *  here, providing things like boolean and combobox option components.
+ *
+ *  It is intended that OptionEditor be subclassed to implement a particular
+ *  options dialog.
+ */
+
+namespace ARDOUR {
+       class Configuration;
+}
+
+class OptionEditorPage;
+
+/** Base class for components of an OptionEditor dialog */
+class OptionEditorComponent
+{
+public:
+       virtual ~OptionEditorComponent() {}
 
-#include <ardour/session.h>
+       /** Called when a configuration parameter's value has changed.
+        *  @param p parameter name
+        */
+       virtual void parameter_changed (std::string const & p) = 0;
 
-#include "ardour_dialog.h"
-#include "editing.h"
-#include "audio_clock.h"
+       /** Called to instruct the object to set its UI state from the configuration */
+       virtual void set_state_from_config () = 0;
+
+       /** Called to instruct the object to add itself to an OptionEditorPage */
+       virtual void add_to_page (OptionEditorPage *) = 0;
+
+       void add_widget_to_page (OptionEditorPage*, Gtk::Widget*);
+       void add_widgets_to_page (OptionEditorPage*, Gtk::Widget*, Gtk::Widget*);
+
+       void set_note (std::string const &);
+
+        virtual Gtk::Widget& tip_widget() = 0;
+
+private:
+       void maybe_add_note (OptionEditorPage *, int);
+       
+       std::string _note;
+};
+
+/** A component which provides a subheading within the dialog */
+class OptionEditorHeading : public OptionEditorComponent
+{
+public:
+       OptionEditorHeading (std::string const &);
+
+       void parameter_changed (std::string const &) {}
+       void set_state_from_config () {}
+       void add_to_page (OptionEditorPage *);
 
-class ARDOUR_UI;
-class PublicEditor;
-class Mixer_UI;
-class IOSelector;
-class GainMeter;
-class PannerUI;
+        Gtk::Widget& tip_widget() { return *_label; }
 
-class OptionEditor : public Gtk::Dialog
+private:
+       Gtk::Label* _label; ///< the label used for the heading
+};
+
+/** A component which provides a box into which a subclass can put arbitrary widgets */
+class OptionEditorBox : public OptionEditorComponent
 {
-  public:
-       OptionEditor (ARDOUR_UI&, PublicEditor&, Mixer_UI&);
-       ~OptionEditor ();
+public:
 
-       void set_session (ARDOUR::Session *);
-       void save ();
+       /** Construct an OpenEditorBox */
+       OptionEditorBox ()
+       {
+               _box = Gtk::manage (new Gtk::VBox);
+               _box->set_spacing (4);
+       }
 
-  private:
-       ARDOUR::Session *session;
-       ARDOUR_UI& ui;
-       PublicEditor& editor;
-       Mixer_UI& mixer;
+       void parameter_changed (std::string const &) = 0;
+       void set_state_from_config () = 0;
+       void add_to_page (OptionEditorPage *);
 
-       Gtk::Notebook notebook;
+        Gtk::Widget& tip_widget() { return *_box->children().front().get_widget(); }
 
-       /* Generic */
+protected:
 
-       void session_control_changed (ARDOUR::Session::ControlType);
-       void queue_session_control_changed (ARDOUR::Session::ControlType);
-       void map_some_session_state (Gtk::CheckButton& button, bool (ARDOUR::Session::*get)() const);
-       gint wm_close (GdkEventAny *);
-       void just_close_win();
-       bool focus_out_event_handler (GdkEventFocus*, void (OptionEditor::*pmf)());
+       Gtk::VBox* _box; ///< constituent box for subclasses to add widgets to
+};
 
-       /* paths */
+/** Base class for components which provide UI to change an option */
+class Option : public OptionEditorComponent
+{
+public:
+       /** Construct an Option.
+        *  @param i Option id (e.g. "plugins-stop-with-transport")
+        *  @param n User-visible name (e.g. "Stop plugins when the transport is stopped")
+        */
+       Option (std::string const & i,
+               std::string const & n
+               )
+               : _id (i),
+                 _name (n)
+       {}
+
+       void parameter_changed (std::string const & p)
+       {
+               if (p == _id) {
+                       set_state_from_config ();
+               }
+       }
 
-       Gtk::Table              path_table;
+       virtual void set_state_from_config () = 0;
+       virtual void add_to_page (OptionEditorPage*) = 0;
 
-       Gtk::Entry              session_raid_entry;
+       std::string id () const {
+               return _id;
+       }
 
-       Gtk::ComboBoxText       native_format_combo;
+protected:
 
-       Glib::RefPtr<Gtk::ListStore> sfdb_paths;
-       Gtk::TreeView sfdb_path_view;
+       std::string _id;
+       std::string _name;
+};
 
-       struct SoundFilePathColumns : public Gtk::TreeModel::ColumnRecord
+/** Component which provides the UI to handle a boolean option using a GTK CheckButton */
+class BoolOption : public Option
+{
+public:
+
+       BoolOption (std::string const &, std::string const &, sigc::slot<bool>, sigc::slot<bool, bool>);
+       void set_state_from_config ();
+       void add_to_page (OptionEditorPage*);
+
+       void set_sensitive (bool yn) {
+               _button->set_sensitive (yn);
+       }
+
+        Gtk::Widget& tip_widget() { return *_button; }
+
+private:
+
+       void toggled ();
+
+       sigc::slot<bool>       _get; ///< slot to get the configuration variable's value
+       sigc::slot<bool, bool> _set;  ///< slot to set the configuration variable's value
+       Gtk::CheckButton*      _button; ///< UI button
+       Gtk::Label*            _label; ///< label for button, so we can use markup
+};
+
+/** Component which provides the UI to handle a string option using a GTK Entry */
+class EntryOption : public Option
+{
+public:
+
+       EntryOption (std::string const &, std::string const &, sigc::slot<std::string>, sigc::slot<bool, std::string>);
+       void set_state_from_config ();
+       void add_to_page (OptionEditorPage*);
+
+        Gtk::Widget& tip_widget() { return *_entry; }
+
+private:
+
+       void activated ();
+
+       sigc::slot<std::string> _get; ///< slot to get the configuration variable's value
+       sigc::slot<bool, std::string> _set;  ///< slot to set the configuration variable's value
+       Gtk::Label* _label; ///< UI label
+       Gtk::Entry* _entry; ///< UI entry
+};
+
+
+/** Component which provides the UI to handle an enumerated option using a GTK ComboBox.
+ *  The template parameter is the enumeration.
+ */
+template <class T>
+class ComboOption : public Option
+{
+public:
+
+       /** Construct an ComboOption.
+        *  @param i id
+        *  @param n User-visible name.
+        *  @param g Slot to get the variable's value.
+        *  @param s Slot to set the variable's value.
+        */
+       ComboOption (
+               std::string const & i,
+               std::string const & n,
+               sigc::slot<T> g,
+               sigc::slot<bool, T> s
+               )
+               : Option (i, n),
+                 _get (g),
+                 _set (s)
        {
-         public:
-           Gtk::TreeModelColumn<std::string> paths;
-
-               SoundFilePathColumns() { add (paths); }
-       };
-       SoundFilePathColumns sfdb_path_columns;
-
-       void setup_path_options();
-       void add_session_paths ();
-       void remove_session_paths ();
-       void native_format_chosen ();
-       void raid_path_changed ();
-
-       /* fades */
-
-       // Gtk::Table           fade_table;
-
-       Gtk::VBox        fade_packer;
-       Gtk::CheckButton auto_xfade_button;
-       Gtk::CheckButton xfade_active_button;
-       Gtk::Label       layer_mode_label;
-       Gtk::ComboBoxText layer_mode_combo;
-       Gtk::Label       xfade_model_label;
-       Gtk::ComboBoxText xfade_model_combo;
-       Gtk::Adjustment  short_xfade_adjustment;
-       Gtk::HScale      short_xfade_slider;
-
-       void auto_xfade_clicked ();
-       void xfade_active_clicked ();
-       void layer_mode_chosen ();
-       void xfade_model_chosen ();
-       void setup_fade_options();
-       void short_xfade_adjustment_changed ();
-
-       /* solo */
-
-       Gtk::VBox        solo_packer;
-       Gtk::CheckButton solo_latched_button;
-       Gtk::CheckButton solo_via_bus_button;
-
-       void solo_latched_clicked();
-       void solo_via_bus_clicked ();
-       
-       void setup_solo_options();
-
-       /* display */
-
-       Gtk::VBox        display_packer;
-       Gtk::CheckButton show_waveforms_button;
-       Gtk::CheckButton show_waveforms_recording_button;
-       Gtk::CheckButton mixer_strip_width_button;
-       Gtk::CheckButton show_measures_button;
-       Gtk::CheckButton follow_playhead_button;
-       Gtk::ComboBoxText meter_hold_combo;
-       Gtk::ComboBoxText meter_falloff_combo;
-
-       void setup_display_options();
-       void show_waveforms_clicked ();
-       void show_waveforms_recording_clicked ();
-       void show_measures_clicked ();
-       void strip_width_clicked ();
-       void follow_playhead_clicked ();
-       void meter_hold_chosen ();
-       void meter_falloff_chosen ();
-       
-       void display_control_changed (Editing::DisplayControl);
+               _label = Gtk::manage (new Gtk::Label (n + ":"));
+               _label->set_alignment (0, 0.5);
+               _combo = Gtk::manage (new Gtk::ComboBoxText);
+               _combo->signal_changed().connect (sigc::mem_fun (*this, &ComboOption::changed));
+       }
+
+       void set_state_from_config () {
+               uint32_t r = 0;
+               while (r < _options.size() && _get () != _options[r]) {
+                       ++r;
+               }
+
+               if (r < _options.size()) {
+                       _combo->set_active (r);
+               }
+       }
+
+       void add_to_page (OptionEditorPage* p)
+       {
+               add_widgets_to_page (p, _label, _combo);
+       }
+
+       /** Add an allowed value for this option.
+        *  @param e Enumeration.
+        *  @param o User-visible name for this value.
+        */
+       void add (T e, std::string const & o) {
+               _options.push_back (e);
+               _combo->append_text (o);
+       }
+
+       void clear () {
+               _combo->clear_items();
+               _options.clear ();
+       }
+
+       void changed () {
+               uint32_t const r = _combo->get_active_row_number ();
+               if (r < _options.size()) {
+                       _set (_options[r]);
+               }
+       }
+
+       void set_sensitive (bool yn) {
+               _combo->set_sensitive (yn);
+       }
+
+        Gtk::Widget& tip_widget() { return *_combo; }
+
+private:
+
+       sigc::slot<T> _get;
+       sigc::slot<bool, T> _set;
+       Gtk::Label* _label;
+       Gtk::ComboBoxText* _combo;
+       std::vector<T> _options;
+};
 
-       /* Sync */
 
-       Gtk::VBox sync_packer;
+/** Component which provides the UI for a GTK HScale.
+ */
+class HSliderOption : public Option
+{
+public:
+
+       /** Construct an ComboOption.
+        *  @param i id
+        *  @param n User-visible name.
+        *  @param g Slot to get the variable's value.
+        *  @param s Slot to set the variable's value.
+        */
+       HSliderOption (
+               std::string const & i,
+               std::string const & n,
+               Gtk::Adjustment &adj
+               )
+               : Option (i, n)
+       {
+               _label = Gtk::manage (new Gtk::Label (n + ":"));
+               _label->set_alignment (0, 0.5);
+               _hscale = Gtk::manage (new Gtk::HScale(adj));
+               _adj = NULL;
+       }
+
+       HSliderOption (
+               std::string const & i,
+               std::string const & n,
+               Gtk::Adjustment *adj,
+               sigc::slot<float> g,
+               sigc::slot<bool, float> s
+               )
+               : Option (i, n)
+               , _get (g)
+               , _set (s)
+               , _adj (adj)
+       {
+               _label = Gtk::manage (new Gtk::Label (n + ":"));
+               _label->set_alignment (0, 0.5);
+               _hscale = Gtk::manage (new Gtk::HScale(*_adj));
+               _adj->signal_value_changed().connect (sigc::mem_fun (*this, &HSliderOption::changed));
+       }
 
-       Gtk::CheckButton send_mtc_button;
-       Gtk::CheckButton send_mmc_button;
-       Gtk::CheckButton jack_time_master_button;
-       Gtk::ComboBoxText slave_type_combo;
-       Gtk::ComboBoxText smpte_fps_combo;
-       AudioClock smpte_offset_clock;
-       Gtk::CheckButton smpte_offset_negative_button;
+       void set_state_from_config () {
+               if (_adj) _adj->set_value (_get());
+       }
 
-       void setup_sync_options ();
-       gint send_mtc_toggled (GdkEventButton*, Gtk::CheckButton*);
+       void changed () {
+               if (_adj) _set (_adj->get_value ());
+       }
 
-       void slave_type_chosen ();
-       void jack_time_master_clicked ();
-       void jack_transport_master_clicked ();
-       void smpte_fps_chosen ();
-       void smpte_offset_chosen ();
-       void smpte_offset_negative_clicked ();
+       void add_to_page (OptionEditorPage* p)
+       {
+               add_widgets_to_page (p, _label, _hscale);
+       }
+
+       void set_sensitive (bool yn) {
+               _hscale->set_sensitive (yn);
+       }
+
+       Gtk::Widget& tip_widget() { return *_hscale; }
+       Gtk::HScale& scale() { return *_hscale; }
+
+private:
+       sigc::slot<float> _get;
+       sigc::slot<bool, float> _set;
+       Gtk::Label* _label;
+       Gtk::HScale* _hscale;
+       Gtk::Adjustment* _adj;
+};
 
-       /* MIDI */
+/** Component which provides the UI to handle an enumerated option using a GTK ComboBox.
+ *  The template parameter is the enumeration.
+ */
+class ComboStringOption : public Option
+{
+public:
+
+       /** Construct an ComboOption.
+        *  @param i id
+        *  @param n User-visible name.
+        *  @param g Slot to get the variable's value.
+        *  @param s Slot to set the variable's value.
+        */
+       ComboStringOption (
+               std::string const & i,
+               std::string const & n,
+               sigc::slot<std::string> g,
+               sigc::slot<bool, std::string> s
+               )
+               : Option (i, n),
+                 _get (g),
+                 _set (s)
+       {
+               _label = Gtk::manage (new Gtk::Label (n + ":"));
+               _label->set_alignment (0, 0.5);
+               _combo = Gtk::manage (new Gtk::ComboBoxText);
+               _combo->signal_changed().connect (sigc::mem_fun (*this, &ComboStringOption::changed));
+       }
 
-       Gtk::VBox  midi_packer;
-       Gtk::CheckButton midi_feedback_button;
-       Gtk::CheckButton midi_control_button;
-       Gtk::CheckButton mmc_control_button;
+       void set_state_from_config () {
+               _combo->set_active_text (_get());
+       }
 
-       Gtk::RadioButton::Group mtc_button_group;
-       Gtk::RadioButton::Group mmc_button_group;
-       Gtk::RadioButton::Group midi_button_group;
+       void add_to_page (OptionEditorPage* p)
+       {
+               add_widgets_to_page (p, _label, _combo);
+       }
+
+       /** Set the allowed strings for this option
+        *  @param strings a vector of allowed strings
+        */
+        void set_popdown_strings (const std::vector<std::string>& strings) {
+               _combo->clear_items ();
+               for (std::vector<std::string>::const_iterator i = strings.begin(); i != strings.end(); ++i) {
+                       _combo->append_text (*i);
+               }
+       }
+
+       void clear () {
+               _combo->clear_items();
+       }
+
+       void changed () {
+               _set (_combo->get_active_text ());
+       }
+
+       void set_sensitive (bool yn) {
+               _combo->set_sensitive (yn);
+       }
+
+        Gtk::Widget& tip_widget() { return *_combo; }
+
+private:
+        sigc::slot<std::string> _get;
+        sigc::slot<bool, std::string> _set;
+       Gtk::Label* _label;
+       Gtk::ComboBoxText* _combo;
+};
 
-       void send_mmc_toggled (Gtk::CheckButton*);
-       void mmc_control_toggled (Gtk::CheckButton*);
-       void midi_control_toggled (Gtk::CheckButton*);
-       void midi_feedback_toggled (Gtk::CheckButton*);
 
-       gint port_online_toggled (GdkEventButton*,MIDI::Port*,Gtk::ToggleButton*);
-       gint port_trace_in_toggled (GdkEventButton*,MIDI::Port*,Gtk::ToggleButton*);
-       gint port_trace_out_toggled (GdkEventButton*,MIDI::Port*,Gtk::ToggleButton*);
-       
-       gint mmc_port_chosen (GdkEventButton*,MIDI::Port*,Gtk::RadioButton*);
-       gint mtc_port_chosen (GdkEventButton*,MIDI::Port*,Gtk::RadioButton*);
-       gint midi_port_chosen (GdkEventButton*,MIDI::Port*,Gtk::RadioButton*);
+/** Component which provides the UI to handle a boolean option which needs
+ *  to be represented as a ComboBox to be clear to the user.
+ */
+class BoolComboOption : public Option
+{
+public:
+
+       BoolComboOption (
+               std::string const &,
+               std::string const &,
+               std::string const &,
+               std::string const &,
+               sigc::slot<bool>,
+               sigc::slot<bool, bool>
+               );
+
+       void set_state_from_config ();
+       void add_to_page (OptionEditorPage *);
+       void changed ();
+       void set_sensitive (bool);
+
+        Gtk::Widget& tip_widget() { return *_combo; }
+
+private:
+
+       sigc::slot<bool> _get;
+       sigc::slot<bool, bool> _set;
+       Gtk::Label* _label;
+       Gtk::ComboBoxText* _combo;
+};
+
+
+
+/** Component which provides the UI to handle an numeric option using a GTK SpinButton */
+template <class T>
+class SpinOption : public Option
+{
+public:
+       /** Construct an SpinOption.
+        *  @param i id
+        *  @param n User-visible name.
+        *  @param g Slot to get the variable's value.
+        *  @param s Slot to set the variable's value.
+        *  @param min Variable minimum value.
+        *  @param max Variable maximum value.
+        *  @param step Step for the spin button.
+        *  @param page Page step for the spin button.
+        *  @param unit Unit name.
+        *  @param scale Scaling factor (such that for a value x in the spinbutton, x * scale is written to the config)
+        */
+       SpinOption (
+               std::string const & i,
+               std::string const & n,
+               sigc::slot<T> g,
+               sigc::slot<bool, T> s,
+               T min,
+               T max,
+               T step,
+               T page,
+               std::string const & unit = "",
+               float scale = 1
+               )
+               : Option (i, n),
+                 _get (g),
+                 _set (s),
+                 _scale (scale)
+       {
+               _label = Gtk::manage (new Gtk::Label (n + ":"));
+               _label->set_alignment (0, 0.5);
+
+               _spin = Gtk::manage (new Gtk::SpinButton);
+               _spin->set_range (min, max);
+               _spin->set_increments (step, page);
+
+               _box = Gtk::manage (new Gtk::HBox);
+               _box->pack_start (*_spin, true, true);
+               _box->set_spacing (4);
+               if (unit.length()) {
+                       _box->pack_start (*Gtk::manage (new Gtk::Label (unit)), false, false);
+               }
+
+               _spin->signal_value_changed().connect (sigc::mem_fun (*this, &SpinOption::changed));
+       }
+
+       void set_state_from_config ()
+       {
+               _spin->set_value (_get () / _scale);
+       }
+
+       void add_to_page (OptionEditorPage* p)
+       {
+               add_widgets_to_page (p, _label, _box);
+       }
+
+       void changed ()
+       {
+               _set (static_cast<T> (_spin->get_value ()) * _scale);
+       }
+
+        Gtk::Widget& tip_widget() { return *_spin; }
+
+private:
+       sigc::slot<T> _get;
+       sigc::slot<bool, T> _set;
+       float _scale;
+       Gtk::Label* _label;
+       Gtk::HBox* _box;
+       Gtk::SpinButton* _spin;
+};
 
-       void map_port_online (MIDI::Port*, Gtk::ToggleButton*);
+class FaderOption : public Option
+{
+public:
 
-       void setup_midi_options();
+       FaderOption (std::string const &, std::string const &, sigc::slot<ARDOUR::gain_t> g, sigc::slot<bool, ARDOUR::gain_t> s);
+       void set_state_from_config ();
+       void add_to_page (OptionEditorPage *);
 
-       enum PortIndex {
-               MtcIndex = 0,
-               MmcIndex = 1,
-               MidiIndex = 2
-       };
+        Gtk::Widget& tip_widget() { return *_db_slider; }
 
-       std::map<MIDI::Port*,std::vector<Gtk::RadioButton*> > port_toggle_buttons;
+private:
+       void db_changed ();
 
-       /* Click */
+       Gtk::Adjustment _db_adjustment;
+       Gtkmm2ext::HSliderController* _db_slider;
+       Gtk::Entry _db_display;
+       Gtk::Label _label;
+       Gtk::HBox _box;
+       Gtk::VBox _fader_centering_box;
+       sigc::slot<ARDOUR::gain_t> _get;
+       sigc::slot<bool, ARDOUR::gain_t> _set;
+};
 
-       IOSelector*   click_io_selector;
-       GainMeter* click_gpm;
-       PannerUI*     click_panner;
-       Gtk::VBox     click_packer;
-       Gtk::Table    click_table;
-       Gtk::Entry    click_path_entry;
-       Gtk::Entry    click_emphasis_path_entry;
-       Gtk::Button   click_browse_button;
-       Gtk::Button   click_emphasis_browse_button;
+class ClockOption : public Option
+{
+public:
+       ClockOption (std::string const &, std::string const &, sigc::slot<std::string>, sigc::slot<bool, std::string>);
+       void set_state_from_config ();
+       void add_to_page (OptionEditorPage *);
+       void set_session (ARDOUR::Session *);
 
-       void setup_click_editor ();
-       void clear_click_editor ();
+        Gtk::Widget& tip_widget() { return _clock; }
+        AudioClock& clock() { return _clock; }
 
-       void click_chosen (std::string paths);
-       void click_emphasis_chosen (std::string paths);
+private:
+       void save_clock_time ();
+       Gtk::Label _label;
+       AudioClock _clock;
+       sigc::slot<std::string> _get;
+       sigc::slot<bool, std::string> _set;
+       ARDOUR::Session *_session;
+};
+
+class DirectoryOption : public Option
+{
+public:
+       DirectoryOption (std::string const &, std::string const &, sigc::slot<std::string>, sigc::slot<bool, std::string>);
 
-       void click_browse_clicked ();
-       void click_emphasis_browse_clicked ();
+       void set_state_from_config ();
+       void add_to_page (OptionEditorPage *);
+
+        Gtk::Widget& tip_widget() { return _file_chooser; }
+
+private:
+       void file_set ();
+       void current_folder_set ();
        
-       void click_sound_changed ();
-       void click_emphasis_sound_changed ();
-
-       /* Auditioner */
-
-       Gtk::VBox     audition_packer;
-       Gtk::HBox     audition_hpacker;
-       Gtk::Label    audition_label;
-       IOSelector*   auditioner_io_selector;
-       GainMeter* auditioner_gpm;
-       PannerUI* auditioner_panner;
-
-       void setup_auditioner_editor ();
-       void clear_auditioner_editor ();
-       void connect_audition_editor ();
-
-       /* keyboard/mouse */
-
-       Gtk::Table keyboard_mouse_table;
-       Gtk::ComboBoxText edit_modifier_combo;
-       Gtk::ComboBoxText delete_modifier_combo;
-       Gtk::ComboBoxText snap_modifier_combo;
-       Gtk::Adjustment delete_button_adjustment;
-       Gtk::SpinButton delete_button_spin;
-       Gtk::Adjustment edit_button_adjustment;
-       Gtk::SpinButton edit_button_spin;
-
-       void setup_keyboard_options ();
-       void delete_modifier_chosen ();
-       void edit_modifier_chosen ();
-       void snap_modifier_chosen ();
-       void edit_button_changed ();
-       void delete_button_changed ();
-
-       /* Miscellany */
-
-       Gtk::VBox misc_packer;
-
-       Gtk::CheckButton auto_connect_inputs_button;
-
-       Gtk::RadioButton auto_connect_output_physical_button;
-       Gtk::RadioButton auto_connect_output_master_button;
-       Gtk::RadioButton auto_connect_output_manual_button;
-       Gtk::RadioButton::Group auto_connect_output_button_group;
-
-       Gtk::CheckButton hw_monitor_button;
-       Gtk::CheckButton sw_monitor_button;
-       Gtk::CheckButton plugins_stop_button;
-       Gtk::CheckButton plugins_on_rec_button;
-       Gtk::CheckButton verify_remove_last_capture_button;
-       Gtk::CheckButton stop_rec_on_xrun_button;
-       Gtk::CheckButton stop_at_end_button;
-       Gtk::CheckButton debug_keyboard_button;
-       Gtk::CheckButton speed_quieten_button;
-
-       void setup_misc_options ();
-       void plugins_stop_with_transport_clicked ();
-       void verify_remove_last_capture_clicked ();
-       void plugins_on_while_recording_clicked ();
-       void auto_connect_inputs_clicked ();
-       void auto_connect_output_physical_clicked ();
-       void auto_connect_output_master_clicked ();
-       void auto_connect_output_manual_clicked ();
-       void hw_monitor_clicked ();
-       void sw_monitor_clicked ();
-       void stop_rec_on_xrun_clicked ();
-       void stop_at_end_clicked ();
-       void debug_keyboard_clicked ();
-       void speed_quieten_clicked ();
-
-       void fixup_combo_size (Gtk::ComboBoxText&, std::vector<std::string>& strings);
+       sigc::slot<std::string> _get; ///< slot to get the configuration variable's value
+       sigc::slot<bool, std::string> _set;  ///< slot to set the configuration variable's value
+       Gtk::FileChooserButton _file_chooser;
+};
+
+/** Class to represent a single page in an OptionEditor's notebook.
+ *  Pages are laid out using a 3-column table; the 1st column is used
+ *  to indent non-headings, and the 2nd and 3rd for actual content.
+ */
+class OptionEditorPage
+{
+public:
+       OptionEditorPage (Gtk::Notebook&, std::string const &);
+
+       Gtk::VBox box;
+       Gtk::Table table;
+       std::list<OptionEditorComponent*> components;
+};
+
+/** The OptionEditor dialog base class */
+class OptionEditor : public ArdourWindow
+{
+public:
+       OptionEditor (ARDOUR::Configuration *, std::string const &);
+       ~OptionEditor ();
+
+       void add_option (std::string const &, OptionEditorComponent *);
+
+       void set_current_page (std::string const &);
+
+protected:
+
+       virtual void parameter_changed (std::string const &);
+
+       ARDOUR::Configuration* _config;
+
+private:
+
+       PBD::ScopedConnection config_connection;
+
+       Gtk::Notebook _notebook;
+       std::map<std::string, OptionEditorPage*> _pages;
 };
 
 #endif /* __gtk_ardour_option_editor_h__ */