merge with master
[ardour.git] / gtk2_ardour / option_editor.h
index f5509c760cc6f5e3d24de557772f4bdbdfe5ebdc..47afa77868f6186be211db07894235c8992619e0 100644 (file)
 #include <gtkmm/comboboxtext.h>
 #include <gtkmm/spinbutton.h>
 #include <gtkmm/table.h>
-#include "ardour_dialog.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.
@@ -53,6 +56,8 @@ class OptionEditorPage;
 class OptionEditorComponent
 {
 public:
+       virtual ~OptionEditorComponent() {}
+
        /** Called when a configuration parameter's value has changed.
         *  @param p parameter name
         */
@@ -66,6 +71,15 @@ public:
 
        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 */
@@ -78,6 +92,8 @@ public:
        void set_state_from_config () {}
        void add_to_page (OptionEditorPage *);
 
+        Gtk::Widget& tip_widget() { return *_label; }
+
 private:
        Gtk::Label* _label; ///< the label used for the heading
 };
@@ -98,14 +114,16 @@ public:
        void set_state_from_config () = 0;
        void add_to_page (OptionEditorPage *);
 
+        Gtk::Widget& tip_widget() { return *_box->children().front().get_widget(); }
+
 protected:
 
        Gtk::VBox* _box; ///< constituent box for subclasses to add widgets to
 };
 
 /** Base class for components which provide UI to change an option */
-class Option : public OptionEditorComponent {
-
+class Option : public OptionEditorComponent
+{
 public:
        /** Construct an Option.
         *  @param i Option id (e.g. "plugins-stop-with-transport")
@@ -132,39 +150,48 @@ public:
                return _id;
        }
 
-private:
+protected:
 
        std::string _id;
        std::string _name;
 };
 
 /** Component which provides the UI to handle a boolean option using a GTK CheckButton */
-class BoolOption : public Option {
-
+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>       _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::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 {
-
+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 ();
@@ -176,12 +203,12 @@ private:
 };
 
 
-/** Component which provides the UI to handle an enumerated option using a GTK CheckButton.
+/** 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 {
-
+class ComboOption : public Option
+{
 public:
 
        /** Construct an ComboOption.
@@ -200,9 +227,9 @@ public:
                  _get (g),
                  _set (s)
        {
-               _label = manage (new Gtk::Label (n + ":"));
-               _label->set_alignment (1, 0.5);
-               _combo = manage (new Gtk::ComboBoxText);
+               _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));
        }
 
@@ -231,6 +258,11 @@ public:
                _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()) {
@@ -238,6 +270,12 @@ public:
                }
        }
 
+       void set_sensitive (bool yn) {
+               _combo->set_sensitive (yn);
+       }
+
+        Gtk::Widget& tip_widget() { return *_combo; }
+
 private:
 
        sigc::slot<T> _get;
@@ -248,6 +286,179 @@ private:
 };
 
 
+/** 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));
+       }
+
+       void set_state_from_config () {
+               if (_adj) _adj->set_value (_get());
+       }
+
+       void changed () {
+               if (_adj) _set (_adj->get_value ());
+       }
+
+       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; }
+
+private:
+       sigc::slot<float> _get;
+       sigc::slot<bool, float> _set;
+       Gtk::Label* _label;
+       Gtk::HScale* _hscale;
+       Gtk::Adjustment* _adj;
+};
+
+/** 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));
+       }
+
+       void set_state_from_config () {
+               _combo->set_active_text (_get());
+       }
+
+       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;
+};
+
+
+/** 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
@@ -282,18 +493,18 @@ public:
                  _set (s),
                  _scale (scale)
        {
-               _label = manage (new Gtk::Label (n + ":"));
-               _label->set_alignment (1, 0.5);
+               _label = Gtk::manage (new Gtk::Label (n + ":"));
+               _label->set_alignment (0, 0.5);
 
-               _spin = manage (new Gtk::SpinButton);
+               _spin = Gtk::manage (new Gtk::SpinButton);
                _spin->set_range (min, max);
                _spin->set_increments (step, page);
 
-               _box = manage (new Gtk::HBox);
+               _box = Gtk::manage (new Gtk::HBox);
                _box->pack_start (*_spin, true, true);
                _box->set_spacing (4);
                if (unit.length()) {
-                       _box->pack_start (*manage (new Gtk::Label (unit)), false, false);
+                       _box->pack_start (*Gtk::manage (new Gtk::Label (unit)), false, false);
                }
 
                _spin->signal_value_changed().connect (sigc::mem_fun (*this, &SpinOption::changed));
@@ -314,6 +525,8 @@ public:
                _set (static_cast<T> (_spin->get_value ()) * _scale);
        }
 
+        Gtk::Widget& tip_widget() { return *_spin; }
+
 private:
        sigc::slot<T> _get;
        sigc::slot<bool, T> _set;
@@ -323,6 +536,68 @@ private:
        Gtk::SpinButton* _spin;
 };
 
+class FaderOption : public Option
+{
+public:
+
+       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 *);
+
+        Gtk::Widget& tip_widget() { return *_db_slider; }
+
+private:
+       void db_changed ();
+
+       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;
+};
+
+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 *);
+
+        Gtk::Widget& tip_widget() { return _clock; }
+        AudioClock& clock() { return _clock; }
+
+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 set_state_from_config ();
+       void add_to_page (OptionEditorPage *);
+
+        Gtk::Widget& tip_widget() { return _file_chooser; }
+
+private:
+       void file_set ();
+       void current_folder_set ();
+       
+       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.
@@ -338,7 +613,7 @@ public:
 };
 
 /** The OptionEditor dialog base class */
-class OptionEditor : public ArdourDialog
+class OptionEditor : public ArdourWindow
 {
 public:
        OptionEditor (ARDOUR::Configuration *, std::string const &);
@@ -346,13 +621,17 @@ public:
 
        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:
 
-       void parameter_changed (std::string const &);
+       PBD::ScopedConnection config_connection;
 
        Gtk::Notebook _notebook;
        std::map<std::string, OptionEditorPage*> _pages;