21 #include "gtk2ardour-config.h"
63 , button_table (initial_button_rows, initial_button_cols)
64 , output_table (initial_output_rows, initial_output_cols)
65 , hAdjustment(0.0, 0.0, 0.0)
66 , vAdjustment(0.0, 0.0, 0.0)
67 , scroller_view(hAdjustment, vAdjustment)
69 , is_scrollable(scrollable)
71 set_name (
"PluginEditor");
72 set_border_width (10);
78 HBox* constraint_hbox = manage (
new HBox);
79 HBox* smaller_hbox = manage (
new HBox);
80 HBox* automation_hbox = manage (
new HBox);
81 smaller_hbox->set_spacing (4);
82 automation_hbox->set_spacing (6);
83 Label* combo_label = manage (
new Label (
_(
"<span size=\"large\">Presets</span>")));
84 combo_label->set_use_markup (
true);
92 smaller_hbox->pack_start (
add_button,
false,
false);
93 smaller_hbox->pack_start (
save_button,
false,
false);
95 smaller_hbox->pack_start (
reset_button,
false,
false, 4);
107 Label* l = manage (
new Label (
_(
"All Automation")));
108 l->set_alignment (1.0, 0.5);
109 automation_hbox->pack_start (*l,
true,
true);
115 constraint_hbox->set_spacing (5);
116 constraint_hbox->set_homogeneous (
false);
118 VBox* v1_box = manage (
new VBox);
119 VBox* v2_box = manage (
new VBox);
125 v1_box->set_spacing (6);
126 v1_box->pack_start (*smaller_hbox,
false,
true);
127 v1_box->pack_start (*automation_hbox,
false,
true);
132 constraint_hbox->pack_end (*v2_box,
false,
false);
133 constraint_hbox->pack_end (*v1_box,
false,
false);
138 scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
169 static const char *digits =
"0123456789";
172 std::size_t first_digit_pos = label.find_first_of(digits);
173 if (first_digit_pos != string::npos) {
176 s << label.substr(first_digit_pos);
183 return c1 == c2 || (isdigit(c1) && isdigit(c2));
187 std::size_t
length, n = 0;
189 length = min(s1.length(), s2.length());
199 std::size_t s1pos, s2pos, n = 0;
203 while (s1pos-- > 0 && s2pos-- > 0) {
222 int output_row, output_col;
223 int button_row, button_col;
224 int output_rows, output_cols;
225 int button_rows, button_cols;
249 bt_frame = manage (
new Frame);
250 bt_frame->set_name (
"BaseFrame");
251 bt_frame->set_label (
_(
"Switches"));
253 hpacker.pack_start(*bt_frame,
true,
true);
255 box = manage (
new VBox);
256 box->set_border_width (5);
257 box->set_spacing (1);
259 frame = manage (
new Frame);
260 frame->set_name (
"BaseFrame");
261 frame->set_label (
_(
"Controls"));
263 hpacker.pack_start(*frame,
true,
true);
265 std::vector<ControlUI *> control_uis;
299 if (!param_docs.empty()) {
303 control_uis.push_back(cui);
310 for (Plugin::PropertyDescriptors::const_iterator d = descs.begin(); d != descs.end(); ++d) {
330 control_uis.push_back(cui);
332 if (!descs.empty()) {
337 std::vector<ControlUI *> cui_controls_list;
338 for (i = 0; i < control_uis.size(); ++i) {
344 cui_controls_list.push_back(cui);
349 if (++button_col == button_cols) {
355 button_table.attach (*cui, button_col, button_col + 1, button_row, button_row+1,
361 output_table.attach (*cui, output_col, output_col + 1, output_row, output_row+1,
366 if (++output_col == output_cols) {
376 string label, previous_label =
"";
377 std::vector<int> numbers_in_labels(cui_controls_list.size());
379 std::vector<float> similarity_scores(cui_controls_list.size());
380 float most_similar = 0.0, least_similar = 1.0;
383 for (vector<ControlUI*>::iterator cuip = cui_controls_list.begin(); cuip != cui_controls_list.end(); ++cuip, ++i) {
384 label = (*cuip)->label.get_text();
390 similarity_scores[i] =
396 ) / (label.length() + previous_label.length());
397 if (numbers_in_labels[i] >= 0) {
398 similarity_scores[i] += (numbers_in_labels[i] == numbers_in_labels[i-1]);
400 least_similar = min(least_similar, similarity_scores[i]);
401 most_similar = max(most_similar, similarity_scores[i]);
403 similarity_scores[0] = 1.0;
407 previous_label = label;
412 float similarity_threshold;
414 if (most_similar > 1.0) {
425 for (vector<ControlUI*>::iterator cuip = cui_controls_list.begin(); cuip != cui_controls_list.end(); ++cuip, ++i) {
435 frame = manage (
new Frame);
436 frame->set_name (
"BaseFrame");
437 frame->set_label (
_(
"Controls"));
438 box = manage (
new VBox);
439 box->set_border_width (5);
440 box->set_spacing (1);
442 hpacker.pack_start(*frame,
true,
true);
445 HSeparator *
split =
new HSeparator();
446 split->set_size_request(-1, 5);
447 box->pack_start(*split,
false,
false, 0);
451 box->pack_start (*cui,
false,
false);
458 if (box->children().empty()) {
467 frame = manage (
new Frame);
468 frame->set_name (
"BaseFrame");
469 frame->set_label(
_(
"Meters"));
471 hpacker.pack_end (*frame,
true,
true);
487 , automate_button (
X_(
""))
510 delete meterinfo->meter;
546 const size_t len = str.copy(buf, 31);
556 const size_t len = str.copy(buf, 31);
579 control_ui = manage (
new ControlUI (param));
580 control_ui->
combo = 0;
581 control_ui->
control = mcontrol;
584 control_ui->
label.set_alignment (0.0, 0.5);
585 control_ui->
label.set_name (
"PluginParameterLabel");
587 control_ui->set_spacing (5);
608 std::vector<std::string> labels;
610 ARDOUR::ScalePoints::const_iterator i = control_ui->
scale_points->begin();
614 labels.push_back(i->first);
617 control_ui->
combo =
new Gtk::ComboBoxText();
619 control_ui->
combo->signal_changed().connect(
626 control_ui->pack_start(control_ui->
label,
true,
true);
627 control_ui->pack_start(*control_ui->
combo,
false,
true);
638 control_ui->
button = manage (
new ToggleButton ());
639 control_ui->
button->set_name (
"PluginEditorButton");
640 control_ui->
button->set_size_request (20, 20);
642 control_ui->pack_start (control_ui->
label,
true,
true);
643 control_ui->pack_start (*control_ui->
button,
false,
true);
653 control_ui->
button->set_active(
true);
661 if (desc.
datatype == Variant::PATH) {
666 control_ui->
file_button = manage(
new Gtk::FileChooserButton(Gtk::FILE_CHOOSER_ACTION_OPEN));
669 control_ui->pack_start (control_ui->
label,
true,
true);
670 control_ui->pack_start (*control_ui->
file_button,
true,
true);
673 control_ui->
file_button->signal_file_set().connect(
701 if (desc.
unit == ParameterDescriptor::MIDI_NOTE) {
709 control_ui->
controller->set_size_request (200, req.height);
710 control_ui->
controller->set_name (
X_(
"ProcessorControlSlider"));
721 control_ui->pack_start (control_ui->
label,
true,
true);
723 control_ui->pack_start (*control_ui->
clickbox,
false,
false);
725 control_ui->pack_start (*control_ui->
controller,
false,
false);
738 }
else if (!is_input) {
740 control_ui->
display = manage (
new EventBox);
741 control_ui->
display->set_name (
"ParameterValueDisplay");
745 control_ui->
display_label->set_name (
"ParameterValueDisplay");
750 control_ui->
display->show_all ();
759 5, 5, FastMeter::Vertical, 0,
761 0x008800ff, 0x008800ff,
762 0x00ff00ff, 0x00ff00ff,
763 0xcccc00ff, 0xcccc00ff,
764 0xffaa00ff, 0xffaa00ff,
776 control_ui->
vbox = manage (
new VBox);
777 control_ui->
hbox = manage (
new HBox);
779 control_ui->
hbox->set_spacing(1);
780 control_ui->
vbox->set_spacing(3);
782 control_ui->
label.set_angle(90);
783 control_ui->
hbox->pack_start (control_ui->
label,
false,
false);
784 control_ui->
hbox->pack_start (*info->
meter,
false,
false);
786 control_ui->
vbox->pack_start (*control_ui->
hbox,
false,
false);
788 control_ui->
vbox->pack_start (*control_ui->
display,
false,
false);
790 control_ui->pack_start (*control_ui->
vbox);
808 using namespace Menu_Helpers;
818 items.push_back (MenuElem (
S_(
"Automation|Manual"),
820 items.push_back (MenuElem (
_(
"Play"),
822 items.push_back (MenuElem (
_(
"Write"),
824 items.push_back (MenuElem (
_(
"Touch"),
834 if ((*i)->controller || (*i)->button) {
853 cui->
button->set_active (
true);
854 cui->
button->set_name (
"PluginEditorButton-active");
856 cui->
button->set_active (
false);
857 cui->
button->set_name (
"PluginEditorButton");
884 if (it->second == val) {
885 cui->
combo->set_active_text(it->first);
892 cui->
button->set_active (
true);
894 cui->
button->set_active (
false);
920 cui->
button->set_name (
"PluginEditorButton-active");
922 cui->
button->set_name (
"PluginEditorButton");
932 string value = cui->
combo->get_active_text();
951 (*i)->controller->stop_updating ();
967 snprintf (buf,
sizeof(buf),
"%.2f", val);
968 (*i)->display_label->set_text (buf);
971 if ((*i)->meterinfo && (*i)->meterinfo->packed) {
973 if (val < (*i)->meterinfo->min) {
974 if ((*i)->meterinfo->min_unbound)
975 (*i)->meterinfo->min = val;
977 val = (*i)->meterinfo->min;
980 if (val > (*i)->meterinfo->max) {
981 if ((*i)->meterinfo->max_unbound)
982 (*i)->meterinfo->max = val;
984 val = (*i)->meterinfo->max;
987 if ((*i)->meterinfo->max > (*i)->meterinfo->min ) {
988 float lval = (val - (*i)->meterinfo->min) / ((*i)->meterinfo->max - (*i)->meterinfo->min) ;
989 (*i)->meterinfo->meter->set (lval );
997 Gtk::FileChooserButton* widget)
1007 c->second->set_filename(value.
get_path());
1009 std::cerr <<
"warning: property change for property with no control" << std::endl;
static std::size_t matching_chars_at_head(const string s1, const string s2)
void set_automation_state(ARDOUR::AutoState state, ControlUI *cui)
virtual std::string get_parameter_docs(uint32_t) const
Gtk::Adjustment * adjustment()
bool integer_printer(char *buf, Gtk::Adjustment &, ControlUI *)
float lower
Minimum value (in Hz, for frequencies)
virtual void announce_property_values()
const Evoral::Parameter parameter() const
bool stop_updating(GdkEventAny *)
sigc::connection super_rapid_connect(const sigc::slot< void > &slot)
LIBGTKMM2EXT_API void set_size_request_to_display_given_text(Gtk::Widget &w, const gchar *text, gint hpadding, gint vpadding)
std::vector< ControlUI * > output_controls
void update_control_display(ControlUI *cui)
void ui_parameter_changed(ControlUI *cui)
void latency_button_clicked()
LIBPBD_API void split(std::string, std::vector< std::string > &, char)
shared_ptr< T > dynamic_pointer_cast(shared_ptr< U > const &r)
static ARDOUR_UI * instance()
virtual bool parameter_is_control(uint32_t) const =0
ArdourDropdown _preset_combo
std::string value_as_string(const ARDOUR::ParameterDescriptor &desc, double v)
Gtkmm2ext::FastMeter * meter
virtual float get_parameter(uint32_t which) const =0
void print_parameter(char *buf, uint32_t len, uint32_t param)
void astate_clicked(ControlUI *)
boost::shared_ptr< Control > control(const Parameter &id, bool create_if_missing=false)
void display_effective_value()
ArdourButton delete_button
LIBPBD_API Transmitter error
void automation_state_changed()
static const int32_t initial_button_rows
boost::shared_ptr< ARDOUR::PluginInsert > insert
ArdourButton latency_button
uint32_t key
for properties
static const int32_t initial_output_rows
std::ostream & endmsg(std::ostream &ostr)
LIBGTKMM2EXT_API void set_popdown_strings(Gtk::ComboBoxText &, const std::vector< std::string > &)
Gtk::ComboBoxText * combo
virtual void set_parameter_automation_state(Evoral::Parameter param, AutoState)
Gtk::FileChooserButton * file_button
ArdourButton bypass_button
void processor_active_changed(boost::weak_ptr< ARDOUR::Processor > p)
Gtk::ScrolledWindow scroller
PBD::ScopedConnectionList control_connections
virtual const PropertyDescriptors & get_supported_properties() const
static int match_or_digit(char c1, char c2)
void control_combo_changed(ControlUI *cui)
Gtk::Expander description_expander
std::vector< ControlUI * > input_controls
Gtk::Expander plugin_analysis_expander
void control_port_toggled(ControlUI *cui)
float upper
Maximum value (in Hz, for frequencies)
static boost::shared_ptr< AutomationController > create(boost::shared_ptr< ARDOUR::Automatable > parent, const Evoral::Parameter ¶m, const ARDOUR::ParameterDescriptor &desc, boost::shared_ptr< ARDOUR::AutomationControl > ac)
Gtk::EventBox focus_button
std::map< uint32_t, ParameterDescriptor > PropertyDescriptors
const ParameterDescriptor & desc() const
virtual double internal_to_interface(double i) const
void set_property(const ARDOUR::ParameterDescriptor &desc, Gtk::FileChooserButton *widget)
Gtkmm2ext::ClickBox * clickbox
Gtk::ToggleButton * button
Gtk::Viewport scroller_view
static const guint32 max_controls_per_column
ArdourButton automation_write_all_button
virtual bool parameter_is_input(uint32_t) const =0
boost::shared_ptr< ARDOUR::AutomationControl > control
virtual int get_parameter_descriptor(uint32_t which, ParameterDescriptor &) const =0
boost::shared_ptr< ARDOUR::ScalePoints > scale_points
Gtk::Button automate_button
virtual void print_parameter(uint32_t, char *, uint32_t len) const =0
ControlUI * build_control_ui(const Evoral::Parameter ¶m, const ARDOUR::ParameterDescriptor &desc, boost::shared_ptr< ARDOUR::AutomationControl > mcontrol, float value, bool is_input)
static const float default_similarity_threshold
static int get_number(string label)
void set_printer(sigc::slot< bool, char *, Gtk::Adjustment & >)
const std::string & get_path() const
LIBPBD_API Transmitter info
LIBARDOUR_API PBD::PropertyDescriptor< bool > active
void toggle_parameter_changed(ControlUI *cui)
ArdourButton automation_manual_all_button
const Parameter & parameter() const
void set_tip(Gtk::Widget &w, const gchar *tip)
void call_slot(EventLoop::InvalidationRecord *, const boost::function< void()> &)
static const int32_t initial_output_cols
boost::shared_ptr< AutomationController > controller
PBD::ScopedConnection active_connection
PBD::Signal2< void, uint32_t, Variant > PropertyChanged
void property_changed(uint32_t key, const ARDOUR::Variant &value)
ArdourButton automation_touch_all_button
bool toggled
True iff parameter is boolean.
static UIConfiguration * config()
PBD::Signal0< void > Changed
virtual std::string describe_parameter(Evoral::Parameter)=0
PBD::Signal0< void > ActiveChanged
virtual double interface_to_internal(double i) const
static const guint32 min_controls_per_column
static std::size_t matching_chars_at_tail(const string s1, const string s2)
boost::shared_ptr< ScalePoints > scale_points
boost::shared_ptr< AutomationControl > automation_control(const Evoral::Parameter &id, bool create_if_missing=false)
Gtk::Menu * automation_menu
GenericPluginUI(boost::shared_ptr< ARDOUR::PluginInsert > plug, bool scrollable=false)
PropertyControls _property_controls
boost::shared_ptr< AutomationList > alist() const
virtual void set_property(uint32_t key, const Variant &value)
AutoState get_parameter_automation_state(Evoral::Parameter param)
boost::shared_ptr< ARDOUR::Plugin > plugin
Gtk::Label _preset_modified
Gtk::Label * display_label
#define MISSING_INVALIDATOR
bool start_updating(GdkEventAny *)
std::vector< ControlUI * > input_controls_with_automation
virtual uint32_t parameter_count() const =0
virtual std::string get_docs() const
Variant::Type datatype
for properties
ArdourButton automation_play_all_button
ArdourButton reset_button
sigc::connection screen_update_connection
bool midinote_printer(char *buf, Gtk::Adjustment &, ControlUI *)
std::string string_compose(const std::string &fmt, const T1 &o1)
ControlUI(const Evoral::Parameter ¶m)
LIBARDOUR_API PBD::PropertyDescriptor< framecnt_t > length
PBD::Signal1< void, AutoState > automation_state_changed
void set_all_automation(ARDOUR::AutoState state)
LIBARDOUR_API PBD::PropertyDescriptor< bool > color
static const int32_t initial_button_cols