X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Foption_editor.h;h=5fbed4ea32d89b5514f49596993a9c56716a11e1;hb=2292e33ee418070c4d12971a72e01eb29dfc8de9;hp=c4a51b9ad56e9c4037cb5b80bade5eaf5f639ab1;hpb=e493b2b7c4fbbbfc457f02babf9546289b430177;p=ardour.git diff --git a/gtk2_ardour/option_editor.h b/gtk2_ardour/option_editor.h index c4a51b9ad5..5fbed4ea32 100644 --- a/gtk2_ardour/option_editor.h +++ b/gtk2_ardour/option_editor.h @@ -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,266 +15,599 @@ 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__ #define __gtk_ardour_option_editor_h__ -#include +#include +#include +#include +#include +#include +#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 + /** 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; -class ARDOUR_UI; -class PublicEditor; -class Mixer_UI; -class IOSelector; -class GainMeter; -class PannerUI; + 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; +}; -class OptionEditor : public ArdourDialog +/** A component which provides a subheading within the dialog */ +class OptionEditorHeading : public OptionEditorComponent { - public: - OptionEditor (ARDOUR_UI&, PublicEditor&, Mixer_UI&); - ~OptionEditor (); +public: + OptionEditorHeading (std::string const &); - void set_session (ARDOUR::Session *); - void save (); + void parameter_changed (std::string const &) {} + void set_state_from_config () {} + void add_to_page (OptionEditorPage *); - private: - ARDOUR::Session *session; - ARDOUR_UI& ui; - PublicEditor& editor; - Mixer_UI& mixer; + Gtk::Widget& tip_widget() { return *_label; } - Gtk::Notebook notebook; +private: + Gtk::Label* _label; ///< the label used for the heading +}; - /* Generic */ +/** A component which provides a box into which a subclass can put arbitrary widgets */ +class OptionEditorBox : public OptionEditorComponent +{ +public: - 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(); - gint focus_out_event_handler (GdkEventFocus*, void (OptionEditor::*pmf)()); + /** Construct an OpenEditorBox */ + OptionEditorBox () + { + _box = Gtk::manage (new Gtk::VBox); + _box->set_spacing (4); + } - /* paths */ + void parameter_changed (std::string const &) = 0; + void set_state_from_config () = 0; + void add_to_page (OptionEditorPage *); - Gtk::Table path_table; + Gtk::Widget& tip_widget() { return *_box->children().front().get_widget(); } - Gtk::Entry session_raid_entry; +protected: - Gtk::Combo native_format_combo; + Gtk::VBox* _box; ///< constituent box for subclasses to add widgets to +}; - void setup_path_options(); - void add_session_paths (); - void remove_session_paths (); - gint native_format_chosen (GdkEventAny *); - void raid_path_changed (); +/** 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 (); + } + } + + virtual void set_state_from_config () = 0; + virtual void add_to_page (OptionEditorPage*) = 0; + + std::string id () const { + return _id; + } + +protected: + + std::string _id; + std::string _name; +}; - /* fades */ +/** Component which provides the UI to handle a boolean option using a GTK CheckButton */ +class BoolOption : public Option +{ +public: - // Gtk::Table fade_table; + BoolOption (std::string const &, std::string const &, sigc::slot, sigc::slot); + void set_state_from_config (); + void add_to_page (OptionEditorPage*); - Gtk::VBox fade_packer; - Gtk::CheckButton auto_xfade_button; - Gtk::CheckButton xfade_active_button; - Gtk::Label layer_mode_label; - Gtk::Combo layer_mode_combo; - Gtk::Label xfade_model_label; - Gtk::Combo xfade_model_combo; - Gtk::Adjustment short_xfade_adjustment; - Gtk::HScale short_xfade_slider; + void set_sensitive (bool yn) { + _button->set_sensitive (yn); + } - void auto_xfade_clicked (); - void xfade_active_clicked (); - gint layer_mode_chosen (GdkEventAny*); - gint xfade_model_chosen (GdkEventAny*); - void setup_fade_options(); - void short_xfade_adjustment_changed (); + Gtk::Widget& tip_widget() { return *_button; } - /* solo */ +private: - Gtk::VBox solo_packer; - Gtk::CheckButton solo_latched_button; - Gtk::CheckButton solo_via_bus_button; + void toggled (); - 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::Combo meter_hold_combo; - Gtk::Combo 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 (); - gint meter_hold_chosen (GdkEventAny *); - gint meter_falloff_chosen (GdkEventAny *); - - void display_control_changed (Editing::DisplayControl); + sigc::slot _get; ///< slot to get the configuration variable's value + sigc::slot _set; ///< slot to set the configuration variable's value + Gtk::CheckButton* _button; ///< UI button +}; - /* Sync */ +/** Component which provides the UI to handle a string option using a GTK Entry */ +class EntryOption : public Option +{ +public: - Gtk::VBox sync_packer; + EntryOption (std::string const &, std::string const &, sigc::slot, sigc::slot); + void set_state_from_config (); + void add_to_page (OptionEditorPage*); - Gtk::CheckButton send_mtc_button; - Gtk::CheckButton send_mmc_button; - Gtk::CheckButton jack_time_master_button; - Gtk::Combo slave_type_combo; - Gtk::Combo smpte_fps_combo; - AudioClock smpte_offset_clock; - Gtk::CheckButton smpte_offset_negative_button; + Gtk::Widget& tip_widget() { return *_entry; } - void setup_sync_options (); - gint send_mtc_toggled (GdkEventButton*, Gtk::CheckButton*); +private: - gint slave_type_chosen (GdkEventAny*); - void jack_time_master_clicked (); - void jack_transport_master_clicked (); - gint smpte_fps_chosen (GdkEventAny*); - void smpte_offset_chosen (); - void smpte_offset_negative_clicked (); + void activated (); - /* MIDI */ + sigc::slot _get; ///< slot to get the configuration variable's value + sigc::slot _set; ///< slot to set the configuration variable's value + Gtk::Label* _label; ///< UI label + Gtk::Entry* _entry; ///< UI entry +}; - Gtk::VBox midi_packer; - Gtk::CheckButton midi_feedback_button; - Gtk::CheckButton midi_control_button; - Gtk::CheckButton mmc_control_button; - void send_mmc_toggled (Gtk::CheckButton*); - void mmc_control_toggled (Gtk::CheckButton*); - void midi_control_toggled (Gtk::CheckButton*); - void midi_feedback_toggled (Gtk::CheckButton*); +/** Component which provides the UI to handle an enumerated option using a GTK ComboBox. + * The template parameter is the enumeration. + */ +template +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 g, + sigc::slot s + ) + : Option (i, n), + _get (g), + _set (s) + { + _label = manage (new Gtk::Label (n + ":")); + _label->set_alignment (0, 0.5); + _combo = 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 _get; + sigc::slot _set; + Gtk::Label* _label; + Gtk::ComboBoxText* _combo; + std::vector _options; +}; - 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*); - void map_port_online (MIDI::Port*, Gtk::ToggleButton*); +/** 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 = manage (new Gtk::Label (n + ":")); + _label->set_alignment (0, 0.5); + _hscale = manage (new Gtk::HScale(adj)); + } + + void set_state_from_config () { } + + 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: + Gtk::Label* _label; + Gtk::HScale* _hscale; +}; - void setup_midi_options(); +/** 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 g, + sigc::slot s + ) + : Option (i, n), + _get (g), + _set (s) + { + _label = manage (new Gtk::Label (n + ":")); + _label->set_alignment (0, 0.5); + _combo = 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& strings) { + _combo->clear_items (); + for (std::vector::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 _get; + sigc::slot _set; + Gtk::Label* _label; + Gtk::ComboBoxText* _combo; +}; - enum PortIndex { - MtcIndex = 0, - MmcIndex = 1, - MidiIndex = 2 - }; - std::map > port_toggle_buttons; +/** 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, + sigc::slot + ); + + 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 _get; + sigc::slot _set; + Gtk::Label* _label; + Gtk::ComboBoxText* _combo; +}; - /* Click */ - 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; - void setup_click_editor (); - void clear_click_editor (); +/** Component which provides the UI to handle an numeric option using a GTK SpinButton */ +template +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 g, + sigc::slot 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 = manage (new Gtk::Label (n + ":")); + _label->set_alignment (0, 0.5); + + _spin = manage (new Gtk::SpinButton); + _spin->set_range (min, max); + _spin->set_increments (step, page); + + _box = 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); + } + + _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 (_spin->get_value ()) * _scale); + } + + Gtk::Widget& tip_widget() { return *_spin; } + +private: + sigc::slot _get; + sigc::slot _set; + float _scale; + Gtk::Label* _label; + Gtk::HBox* _box; + Gtk::SpinButton* _spin; +}; + +class FaderOption : public Option +{ +public: + + FaderOption (std::string const &, std::string const &, sigc::slot g, sigc::slot 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; + Glib::RefPtr _pix; + Glib::RefPtr _pix_desensitised; + Gtk::Entry _db_display; + Gtk::Label _label; + Gtk::HBox _box; + Gtk::VBox _fader_centering_box; + sigc::slot _get; + sigc::slot _set; +}; + +class ClockOption : public Option +{ +public: + ClockOption (std::string const &, std::string const &, sigc::slot, sigc::slot); + void set_state_from_config (); + void add_to_page (OptionEditorPage *); + void set_session (ARDOUR::Session *); - void click_chosen (vector paths, bool ignore); - void click_emphasis_chosen (vector paths, bool ignore); + Gtk::Widget& tip_widget() { return _clock; } + AudioClock& clock() { return _clock; } - void click_browse_clicked (); - void click_emphasis_browse_clicked (); +private: + void save_clock_time (); + Gtk::Label _label; + AudioClock _clock; + sigc::slot _get; + sigc::slot _set; + ARDOUR::Session *_session; +}; + +class DirectoryOption : public Option +{ +public: + DirectoryOption (std::string const &, std::string const &, sigc::slot, sigc::slot); + + 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::Combo edit_modifier_combo; - Gtk::Combo delete_modifier_combo; - Gtk::Combo 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 (); - gint delete_modifier_chosen (GdkEventAny*); - gint edit_modifier_chosen (GdkEventAny*); - gint snap_modifier_chosen (GdkEventAny*); - 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::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::Combo&, vector& strings); + sigc::slot _get; ///< slot to get the configuration variable's value + sigc::slot _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 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 _pages; }; #endif /* __gtk_ardour_option_editor_h__ */