GUI limitation: Require engine to add/remove tracks/busses
[ardour.git] / gtk2_ardour / option_editor.cc
index f34bab1b2be40abf7d53f9b3aec56c82135a0dd2..b685e789472c35f5e3e0455c7bf67509500dde34 100644 (file)
@@ -59,7 +59,7 @@ OptionEditorComponent::add_widget_to_page (OptionEditorPage* p, Gtk::Widget* w)
 }
 
 void
-OptionEditorComponent::add_widgets_to_page (OptionEditorPage* p, Gtk::Widget* wa, Gtk::Widget* wb)
+OptionEditorComponent::add_widgets_to_page (OptionEditorPage* p, Gtk::Widget* wa, Gtk::Widget* wb, bool expand)
 {
        int const n = p->table.property_n_rows();
        int m = n + 1;
@@ -69,8 +69,13 @@ OptionEditorComponent::add_widgets_to_page (OptionEditorPage* p, Gtk::Widget* wa
 
        p->table.resize (m, 3);
        p->table.attach (*wa, 1, 2, n, n + 1, FILL);
-       p->table.attach (*wb, 2, 3, n, n + 1, FILL | EXPAND);
-
+       if (expand) {
+               p->table.attach (*wb, 2, 3, n, n + 1, FILL | EXPAND);
+       } else {
+               Alignment* a = manage (new Alignment (0, 0.5, 0, 1.0));
+               a->add (*wb);
+               p->table.attach (*a, 2, 3, n, n + 1, FILL | EXPAND);
+       }
        maybe_add_note (p, n + 1);
 }
 
@@ -78,8 +83,9 @@ void
 OptionEditorComponent::maybe_add_note (OptionEditorPage* p, int n)
 {
        if (!_note.empty ()) {
-               Gtk::Label* l = manage (new Gtk::Label (string_compose (X_("<i>%1</i>"), _note)));
+               Gtk::Label* l = manage (left_aligned_label (string_compose (X_("<i>%1</i>"), _note)));
                l->set_use_markup (true);
+               l->set_line_wrap (true);
                p->table.attach (*l, 1, 3, n, n + 1, FILL | EXPAND);
        }
 }
@@ -90,6 +96,8 @@ OptionEditorComponent::set_note (string const & n)
        _note = n;
 }
 
+/*--------------------------*/
+
 OptionEditorHeading::OptionEditorHeading (string const & h)
 {
        std::stringstream s;
@@ -98,46 +106,37 @@ OptionEditorHeading::OptionEditorHeading (string const & h)
        _label->set_use_markup (true);
 }
 
+/*--------------------------*/
+
 void
 OptionEditorHeading::add_to_page (OptionEditorPage* p)
 {
        int const n = p->table.property_n_rows();
-       p->table.resize (n + 2, 3);
+       if (!_note.empty ()) {
+               p->table.resize (n + 3, 3);
+       } else {
+               p->table.resize (n + 2, 3);
+       }
 
        p->table.attach (*manage (new Label ("")), 0, 3, n, n + 1, FILL | EXPAND);
        p->table.attach (*_label, 0, 3, n + 1, n + 2, FILL | EXPAND);
+       maybe_add_note (p, n + 2);
 }
 
-void
-OptionEditorBox::add_to_page (OptionEditorPage* p)
-{
-       add_widget_to_page (p, _box);
-}
-
-RcActionButton::RcActionButton (std::string const & t, const Glib::SignalProxy0< void >::SlotType & slot, std::string const & l)
-       : _label (NULL)
-{
-       _button = manage (new Button (t));
-       _button->signal_clicked().connect (slot);
-       if (!l.empty ()) {
-               _label = manage (right_aligned_label (l));
-       }
-}
+/*--------------------------*/
 
 void
-RcActionButton::add_to_page (OptionEditorPage *p)
+OptionEditorBlank::add_to_page (OptionEditorPage* p)
 {
        int const n = p->table.property_n_rows();
-       int m = n + 1;
-       p->table.resize (m, 3);
-       if (_label) {
-               p->table.attach (*_label,  1, 2, n, n + 1, FILL | EXPAND);
-               p->table.attach (*_button, 2, 3, n, n + 1, FILL | EXPAND);
-       } else {
-               p->table.attach (*_button, 1, 3, n, n + 1, FILL | EXPAND);
-       }
+       p->table.resize (n + 1, 3);
+       p->table.attach (_dummy, 2, 3, n, n + 1, FILL | EXPAND, SHRINK, 0, 0);
+       _dummy.set_size_request (-1, 1);
+       _dummy.show ();
 }
 
+/*--------------------------*/
+
 RcConfigDisplay::RcConfigDisplay (string const & i, string const & n, sigc::slot<string> g, char s)
        : _get (g)
        , _id (i)
@@ -177,6 +176,33 @@ RcConfigDisplay::add_to_page (OptionEditorPage *p)
        p->table.attach (*_info,  2, 3, n, n + 1, FILL | EXPAND);
 }
 
+/*--------------------------*/
+
+RcActionButton::RcActionButton (std::string const & t, const Glib::SignalProxy0< void >::SlotType & slot, std::string const & l)
+       : _label (NULL)
+{
+       _button = manage (new Button (t));
+       _button->signal_clicked().connect (slot);
+       if (!l.empty ()) {
+               _label = manage (right_aligned_label (l));
+       }
+}
+
+void
+RcActionButton::add_to_page (OptionEditorPage *p)
+{
+       int const n = p->table.property_n_rows();
+       int m = n + 1;
+       p->table.resize (m, 3);
+       if (_label) {
+               p->table.attach (*_label,  1, 2, n, n + 1, FILL | EXPAND);
+               p->table.attach (*_button, 2, 3, n, n + 1, FILL | EXPAND);
+       } else {
+               p->table.attach (*_button, 1, 3, n, n + 1, FILL | EXPAND);
+       }
+}
+
+/*--------------------------*/
 
 BoolOption::BoolOption (string const & i, string const & n, sigc::slot<bool> g, sigc::slot<bool, bool> s)
        : Option (i, n),
@@ -211,6 +237,8 @@ BoolOption::toggled ()
        }
 }
 
+/*--------------------------*/
+
 RouteDisplayBoolOption::RouteDisplayBoolOption (string const & i, string const & n, sigc::slot<bool> g, sigc::slot<bool, bool> s)
        : BoolOption (i, n, g, s)
 {
@@ -223,6 +251,8 @@ RouteDisplayBoolOption::toggled ()
        BoolOption::toggled ();
 }
 
+/*--------------------------*/
+
 EntryOption::EntryOption (string const & i, string const & n, sigc::slot<string> g, sigc::slot<bool, string> s)
        : Option (i, n),
          _get (g),
@@ -278,6 +308,123 @@ EntryOption::focus_out (GdkEventFocus*)
        return true;
 }
 
+/*--------------------------*/
+HSliderOption::HSliderOption (
+               std::string const& i,
+               std::string const& n,
+               sigc::slot<float> g,
+               sigc::slot<bool, float> s,
+               double lower, double upper,
+               double step_increment,
+               double page_increment,
+               double mult,
+               bool logarithmic
+               )
+       : Option (i, n)
+       , _get (g)
+       , _set (s)
+       , _adj (lower, lower, upper, step_increment, page_increment, 0)
+       , _hscale (_adj)
+       , _label (n + ":")
+       , _mult (mult)
+       , _log (logarithmic)
+{
+       _label.set_alignment (0, 0.5);
+       _label.set_name ("OptionsLabel");
+       _adj.set_value (_get());
+       _adj.signal_value_changed().connect (sigc::mem_fun (*this, &HSliderOption::changed));
+       _hscale.set_update_policy (Gtk::UPDATE_DISCONTINUOUS);
+}
+
+void
+HSliderOption::set_state_from_config ()
+{
+       if (_log) {
+               _adj.set_value (log10(_get()) / _mult);
+       } else {
+               _adj.set_value (_get() / _mult);
+       }
+}
+
+void
+HSliderOption::changed ()
+{
+       if (_log) {
+               _set (pow (10, _adj.get_value () * _mult));
+       } else {
+               _set (_adj.get_value () * _mult);
+       }
+}
+
+void
+HSliderOption::add_to_page (OptionEditorPage* p)
+{
+       add_widgets_to_page (p, &_label, &_hscale);
+}
+
+void
+HSliderOption::set_sensitive (bool yn)
+{
+       _hscale.set_sensitive (yn);
+}
+
+/*--------------------------*/
+
+ComboStringOption::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
+ComboStringOption::set_state_from_config () {
+       _combo->set_active_text (_get());
+}
+
+void
+ComboStringOption::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
+ComboStringOption::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
+ComboStringOption::clear () {
+       _combo->clear_items();
+}
+
+void
+ComboStringOption::changed () {
+       _set (_combo->get_active_text ());
+}
+
+void
+ComboStringOption::set_sensitive (bool yn) {
+       _combo->set_sensitive (yn);
+}
+
+/*--------------------------*/
+
 /** Construct a BoolComboOption.
  *  @param i id
  *  @param n User-visible name.
@@ -330,7 +477,7 @@ BoolComboOption::set_sensitive (bool yn)
        _combo->set_sensitive (yn);
 }
 
-
+/*--------------------------*/
 
 FaderOption::FaderOption (string const & i, string const & n, sigc::slot<gain_t> g, sigc::slot<bool, gain_t> s)
        : Option (i, n)
@@ -338,7 +485,7 @@ FaderOption::FaderOption (string const & i, string const & n, sigc::slot<gain_t>
        , _get (g)
        , _set (s)
 {
-       _db_slider = manage (new HSliderController (&_db_adjustment, boost::shared_ptr<PBD::Controllable>(), 115, 18));
+       _db_slider = manage (new ArdourWidgets::HSliderController (&_db_adjustment, boost::shared_ptr<PBD::Controllable>(), 220, 18));
 
        _label.set_text (n + ":");
        _label.set_alignment (0, 0.5);
@@ -350,9 +497,10 @@ FaderOption::FaderOption (string const & i, string const & n, sigc::slot<gain_t>
        _box.set_homogeneous (false);
        _box.pack_start (_fader_centering_box, false, false);
        _box.pack_start (_db_display, false, false);
+       _box.pack_start (*manage (new Label ("dB")), false, false);
        _box.show_all ();
 
-       set_size_request_to_display_given_text (_db_display, "-99.00", 12, 12);
+       set_size_request_to_display_given_text (_db_display, "-99.00", 12, 0);
 
        _db_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &FaderOption::db_changed));
        _db_display.signal_activate().connect (sigc::mem_fun (*this, &FaderOption::on_activate));
@@ -408,6 +556,8 @@ FaderOption::add_to_page (OptionEditorPage* p)
        add_widgets_to_page (p, &_label, &_box);
 }
 
+/*--------------------------*/
+
 ClockOption::ClockOption (string const & i, string const & n, sigc::slot<std::string> g, sigc::slot<bool, std::string> s)
        : Option (i, n)
        , _clock (X_("timecode-offset"), true, X_(""), true, false, true, false)
@@ -424,7 +574,7 @@ void
 ClockOption::set_state_from_config ()
 {
        Timecode::Time TC;
-       framepos_t when;
+       samplepos_t when;
        if (!Timecode::parse_timecode_format(_get(), TC)) {
                _clock.set (0, true);
        }
@@ -456,16 +606,61 @@ ClockOption::set_session (Session* s)
        _clock.set_session (s);
 }
 
+/*--------------------------*/
+
+WidgetOption::WidgetOption (string const & i, string const & n, Gtk::Widget& w)
+       : Option (i, n)
+       , _widget (&w)
+{
+}
+
+void
+WidgetOption::add_to_page (OptionEditorPage* p)
+{
+       add_widget_to_page (p, _widget);
+}
+
+/*--------------------------*/
+
+OptionEditorPage::OptionEditorPage ()
+       : table (1, 3)
+{
+       init ();
+}
+
 OptionEditorPage::OptionEditorPage (Gtk::Notebook& n, std::string const & t)
        : table (1, 3)
 {
-       table.set_spacings (4);
-       table.set_col_spacing (0, 32);
+       init ();
        box.pack_start (table, false, false);
        box.set_border_width (4);
        n.append_page (box, t);
 }
 
+void
+OptionEditorPage::init ()
+{
+       table.set_spacings (4);
+       table.set_col_spacing (0, 32);
+}
+
+/*--------------------------*/
+
+void
+OptionEditorMiniPage::add_to_page (OptionEditorPage* p)
+{
+       int const n = p->table.property_n_rows();
+       int m = n + 1;
+       if (!_note.empty ()) {
+               ++m;
+       }
+       p->table.resize (m, 3);
+       p->table.attach (box, 0, 3, n, n + 1, FILL | EXPAND, SHRINK, 0, 0);
+       maybe_add_note (p, n + 1);
+}
+
+/*--------------------------*/
+
 /** Construct an OptionEditor.
  *  @param o Configuration to edit.
  *  @param t Title for the dialog.
@@ -645,6 +840,7 @@ OptionEditor::set_current_page (string const & p)
 
 }
 
+/*--------------------------*/
 
 DirectoryOption::DirectoryOption (string const & i, string const & n, sigc::slot<string> g, sigc::slot<bool, string> s)
        : Option (i, n)
@@ -655,7 +851,6 @@ DirectoryOption::DirectoryOption (string const & i, string const & n, sigc::slot
        _file_chooser.signal_selection_changed().connect (sigc::mem_fun (*this, &DirectoryOption::selection_changed));
 }
 
-
 void
 DirectoryOption::set_state_from_config ()
 {
@@ -683,8 +878,12 @@ OptionEditorContainer::OptionEditorContainer (PBD::Configuration* c, string cons
        : OptionEditor (c)
 {
        set_border_width (4);
-       hpacker.pack_start (treeview(), false, false);
-       hpacker.pack_start (notebook(), true, true);
+       Frame* f = manage (new Frame ());
+       f->add (treeview());
+       f->set_shadow_type (Gtk::SHADOW_OUT);
+       f->set_border_width (0);
+       hpacker.pack_start (*f, false, false, 4);
+       hpacker.pack_start (notebook(), false, false);
        pack_start (hpacker, true, true);
 
        show_all ();
@@ -695,8 +894,12 @@ OptionEditorWindow::OptionEditorWindow (PBD::Configuration* c, string const& str
        , ArdourWindow (str)
 {
        container.set_border_width (4);
-       hpacker.pack_start (treeview(), false, false);
-       hpacker.pack_start (notebook(), true, true);
+       Frame* f = manage (new Frame ());
+       f->add (treeview());
+       f->set_shadow_type (Gtk::SHADOW_OUT);
+       f->set_border_width (0);
+       hpacker.pack_start (*f, false, false);
+       hpacker.pack_start (notebook(), true, true, 4);
 
        container.pack_start (hpacker, true, true);