diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2014-01-10 14:53:03 -0500 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2014-01-10 14:53:03 -0500 |
commit | d15fda6d751a465d278f477923075d4783f3b1ca (patch) | |
tree | 99e36ff934f50d9c980dbeab09ad021cda3d098c /gtk2_ardour | |
parent | 22c303d8f6c355a7229eb459cedf4fbdf0eb3c1d (diff) | |
parent | 0bdf4c25cfee8cf2408d2b1367f2c5e5c8c509b1 (diff) |
fix merge errors with master
Diffstat (limited to 'gtk2_ardour')
-rw-r--r-- | gtk2_ardour/ardev_common.sh.in | 2 | ||||
-rwxr-xr-x | gtk2_ardour/artest | 25 | ||||
-rw-r--r-- | gtk2_ardour/mixer_strip.cc | 54 | ||||
-rw-r--r-- | gtk2_ardour/mixer_strip.h | 2 | ||||
-rw-r--r-- | gtk2_ardour/mono_panner.cc | 609 | ||||
-rw-r--r-- | gtk2_ardour/mono_panner.h | 11 | ||||
-rw-r--r-- | gtk2_ardour/panner_ui.cc | 160 | ||||
-rw-r--r-- | gtk2_ardour/panner_ui.h | 6 | ||||
-rw-r--r-- | gtk2_ardour/processor_box.cc | 35 | ||||
-rw-r--r-- | gtk2_ardour/processor_box.h | 2 | ||||
-rw-r--r-- | gtk2_ardour/stereo_panner.cc | 150 | ||||
-rw-r--r-- | gtk2_ardour/stereo_panner.h | 11 |
12 files changed, 656 insertions, 411 deletions
diff --git a/gtk2_ardour/ardev_common.sh.in b/gtk2_ardour/ardev_common.sh.in index dd014f5fd9..703e388e5a 100644 --- a/gtk2_ardour/ardev_common.sh.in +++ b/gtk2_ardour/ardev_common.sh.in @@ -12,7 +12,7 @@ libs=$TOP/@LIBS@ export ARDOUR_PATH=$TOP/gtk2_ardour/icons:$TOP/gtk2_ardour/pixmaps:$TOP/build/gtk2_ardour:$TOP/gtk2_ardour:. export ARDOUR_SURFACES_PATH=$libs/surfaces/osc:$libs/surfaces/generic_midi:$libs/surfaces/tranzport:$libs/surfaces/powermate:$libs/surfaces/mackie:$libs/surfaces/wiimote -export ARDOUR_PANNER_PATH=$libs/panners/2in2out:$libs/panners/1in2out:$libs/panners/vbap +export ARDOUR_PANNER_PATH=$libs/panners export ARDOUR_DATA_PATH=$TOP:$TOP/build:$TOP/gtk2_ardour:$TOP/build/gtk2_ardour:. export ARDOUR_MIDIMAPS_PATH=$TOP/midi_maps:. export ARDOUR_MCP_PATH=$TOP/mcp:. diff --git a/gtk2_ardour/artest b/gtk2_ardour/artest new file mode 100755 index 0000000000..cd2a55cdd5 --- /dev/null +++ b/gtk2_ardour/artest @@ -0,0 +1,25 @@ +#!/bin/sh +. `dirname "$0"`/../build/gtk2_ardour/ardev_common_waf.sh + +LIBS_DIR=$TOP/build/libs + +run_tests () { + echo "" + echo "-------------------------------------------" + echo "Running tests for $1..." + echo "-------------------------------------------" + echo "" + $2 $LIBS_DIR/$1/run-tests + echo "" +} + +if [ $# -gt 0 ]; then + run_tests $1 $2 + exit +fi + +run_tests audiographer +run_tests midi++2 +run_tests evoral +run_tests pbd +run_tests ardour diff --git a/gtk2_ardour/mixer_strip.cc b/gtk2_ardour/mixer_strip.cc index aa49e20d0c..e7c3f138b8 100644 --- a/gtk2_ardour/mixer_strip.cc +++ b/gtk2_ardour/mixer_strip.cc @@ -41,6 +41,7 @@ #include "ardour/pannable.h" #include "ardour/panner.h" #include "ardour/panner_shell.h" +#include "ardour/panner_manager.h" #include "ardour/port.h" #include "ardour/profile.h" #include "ardour/route.h" @@ -515,7 +516,10 @@ MixerStrip::set_route (boost::shared_ptr<Route> rt) _route->output()->changed.connect (*this, invalidator (*this), boost::bind (&MixerStrip::update_output_display, this), gui_context()); _route->route_group_changed.connect (route_connections, invalidator (*this), boost::bind (&MixerStrip::route_group_changed, this), gui_context()); + _route->io_changed.connect (route_connections, invalidator (*this), boost::bind (&MixerStrip::io_changed_proxy, this), gui_context ()); + if (_route->panner_shell()) { + update_panner_choices(); _route->panner_shell()->Changed.connect (route_connections, invalidator (*this), boost::bind (&MixerStrip::connect_to_pan, this), gui_context()); } @@ -1019,9 +1023,48 @@ MixerStrip::connect_to_pan () p->automation_state_changed.connect (panstate_connection, invalidator (*this), boost::bind (&PannerUI::pan_automation_state_changed, &panners), gui_context()); p->automation_style_changed.connect (panstyle_connection, invalidator (*this), boost::bind (&PannerUI::pan_automation_style_changed, &panners), gui_context()); - panners.panshell_changed (); + /* This call reduncant, PannerUI::set_panner() connects to _panshell->Changed itself + * However, that only works a panner was previously set. + * + * PannerUI must remain subscribed to _panshell->Changed() in case + * we switch the panner eg. AUX-Send and back + * _route->panner_shell()->Changed() vs _panshell->Changed + */ + if (panners._panner == 0) { + panners.panshell_changed (); + } } +void +MixerStrip::update_panner_choices () +{ + ENSURE_GUI_THREAD (*this, &MixerStrip::update_panner_choices) + if (!_route->panner_shell()) { return; } + + int in = _route->output()->n_ports().n_audio(); + int out = in; + + if (_route->panner()) { + in = _route->panner()->in().n_audio(); + } + + if (out < 2 || in == 0) { + panners.set_available_panners(_route, std::map<std::string,std::string>()); + return; + } + + std::map<std::string,std::string> panner_list; + std::list<PannerInfo*> panner_info = PannerManager::instance().panner_info; + /* get available panners for current configuration. */ + for (list<PannerInfo*>::iterator p = panner_info.begin(); p != panner_info.end(); ++p) { + PanPluginDescriptor* d = &(*p)->descriptor; + if (d->in != -1 && d->in != in) continue; + if (d->out != -1 && d->out != out) continue; + if (d->in == -1 && d->out == -1 && out <= 2) continue; + panner_list.insert(std::pair<std::string,std::string>(d->panner_uri,d->name)); + } + panners.set_available_panners(_route, panner_list); +} /* * Output port labelling @@ -1273,6 +1316,12 @@ MixerStrip::diskstream_changed () } void +MixerStrip::io_changed_proxy () +{ + Glib::signal_idle().connect_once (sigc::mem_fun (*this, &MixerStrip::update_panner_choices)); +} + +void MixerStrip::port_connected_or_disconnected (boost::weak_ptr<Port> wa, boost::weak_ptr<Port> wb) { boost::shared_ptr<Port> a = wa.lock (); @@ -1843,6 +1892,8 @@ MixerStrip::show_send (boost::shared_ptr<Send> send) gain_meter().setup_meters (); panner_ui().set_panner (_current_delivery->panner_shell(), _current_delivery->panner()); + panner_ui().set_available_panners(boost::shared_ptr<ARDOUR::Route>(), std::map<std::string,std::string>()); + panner_ui().setup_pan (); /* make sure the send has audio output */ @@ -1884,6 +1935,7 @@ MixerStrip::revert_to_default_display () gain_meter().setup_meters (); panner_ui().set_panner (_route->main_outs()->panner_shell(), _route->main_outs()->panner()); + update_panner_choices(); panner_ui().setup_pan (); if (has_audio_outputs ()) { diff --git a/gtk2_ardour/mixer_strip.h b/gtk2_ardour/mixer_strip.h index fe10070fbb..883bfffdba 100644 --- a/gtk2_ardour/mixer_strip.h +++ b/gtk2_ardour/mixer_strip.h @@ -226,6 +226,7 @@ class MixerStrip : public RouteUI, public Gtk::EventBox void edit_output_configuration (); void diskstream_changed (); + void io_changed_proxy (); Gtk::Menu *send_action_menu; Gtk::MenuItem* rename_menu_item; @@ -237,6 +238,7 @@ class MixerStrip : public RouteUI, public Gtk::EventBox PBD::ScopedConnection panstate_connection; PBD::ScopedConnection panstyle_connection; void connect_to_pan (); + void update_panner_choices (); void update_diskstream_display (); void update_input_display (); diff --git a/gtk2_ardour/mono_panner.cc b/gtk2_ardour/mono_panner.cc index e29ec01b70..1a2b685aeb 100644 --- a/gtk2_ardour/mono_panner.cc +++ b/gtk2_ardour/mono_panner.cc @@ -23,6 +23,7 @@ #include <cmath> #include <gtkmm/window.h> +#include <pangomm/layout.h> #include "pbd/controllable.h" #include "pbd/compose.h" @@ -35,6 +36,7 @@ #include "ardour/pannable.h" #include "ardour/panner.h" +#include "ardour/panner_shell.h" #include "ardour_ui.h" #include "global_signals.h" @@ -57,23 +59,39 @@ static const int top_step = 2; MonoPanner::ColorScheme MonoPanner::colors; bool MonoPanner::have_colors = false; -MonoPanner::MonoPanner (boost::shared_ptr<ARDOUR::Panner> panner) - : PannerInterface (panner) +Pango::AttrList MonoPanner::panner_font_attributes; +bool MonoPanner::have_font = false; + +MonoPanner::MonoPanner (boost::shared_ptr<ARDOUR::PannerShell> p) + : PannerInterface (p->panner()) + , _panner_shell (p) , position_control (_panner->pannable()->pan_azimuth_control) - , drag_start_x (0) - , last_drag_x (0) - , accumulated_delta (0) - , detented (false) - , position_binder (position_control) + , drag_start_x (0) + , last_drag_x (0) + , accumulated_delta (0) + , detented (false) + , position_binder (position_control) , _dragging (false) { - if (!have_colors) { - set_colors (); - have_colors = true; - } + if (!have_colors) { + set_colors (); + have_colors = true; + } + if (!have_font) { + Pango::FontDescription font; + Pango::AttrFontDesc* font_attr; + font = Pango::FontDescription ("ArdourMono"); + font.set_weight (Pango::WEIGHT_BOLD); + font.set_size(9 * PANGO_SCALE); + font_attr = new Pango::AttrFontDesc (Pango::Attribute::create_attr_font_desc (font)); + panner_font_attributes.change(*font_attr); + delete font_attr; + have_font = true; + } - position_control->Changed.connect (connections, invalidator(*this), boost::bind (&MonoPanner::value_change, this), gui_context()); + position_control->Changed.connect (connections, invalidator(*this), boost::bind (&MonoPanner::value_change, this), gui_context()); + _panner_shell->Changed.connect (connections, invalidator (*this), boost::bind (&MonoPanner::bypass_handler, this), gui_context()); ColorsChanged.connect (sigc::mem_fun (*this, &MonoPanner::color_handler)); set_tooltip (); @@ -87,21 +105,25 @@ MonoPanner::~MonoPanner () void MonoPanner::set_tooltip () { - double pos = position_control->get_value(); // 0..1 + if (_panner_shell->bypassed()) { + _tooltip.set_tip (_("bypassed")); + return; + } + double pos = position_control->get_value(); // 0..1 - /* We show the position of the center of the image relative to the left & right. - This is expressed as a pair of percentage values that ranges from (100,0) - (hard left) through (50,50) (hard center) to (0,100) (hard right). + /* We show the position of the center of the image relative to the left & right. + This is expressed as a pair of percentage values that ranges from (100,0) + (hard left) through (50,50) (hard center) to (0,100) (hard right). - This is pretty wierd, but its the way audio engineers expect it. Just remember that - the center of the USA isn't Kansas, its (50LA, 50NY) and it will all make sense. - */ + This is pretty wierd, but its the way audio engineers expect it. Just remember that + the center of the USA isn't Kansas, its (50LA, 50NY) and it will all make sense. + */ - char buf[64]; - snprintf (buf, sizeof (buf), _("L:%3d R:%3d"), - (int) rint (100.0 * (1.0 - pos)), - (int) rint (100.0 * pos)); - _tooltip.set_tip (buf); + char buf[64]; + snprintf (buf, sizeof (buf), _("L:%3d R:%3d"), + (int) rint (100.0 * (1.0 - pos)), + (int) rint (100.0 * pos)); + _tooltip.set_tip (buf); } bool @@ -109,137 +131,146 @@ MonoPanner::on_expose_event (GdkEventExpose*) { Glib::RefPtr<Gdk::Window> win (get_window()); Glib::RefPtr<Gdk::GC> gc (get_style()->get_base_gc (get_state())); - Cairo::RefPtr<Cairo::Context> context = get_window()->create_cairo_context(); - - int width, height; - double pos = position_control->get_value (); /* 0..1 */ - uint32_t o, f, t, b, pf, po; - const double corner_radius = 5; - - width = get_width(); - height = get_height (); - - o = colors.outline; - f = colors.fill; - t = colors.text; - b = colors.background; - pf = colors.pos_fill; - po = colors.pos_outline; - - /* background */ - - context->set_source_rgba (UINT_RGBA_R_FLT(b), UINT_RGBA_G_FLT(b), UINT_RGBA_B_FLT(b), UINT_RGBA_A_FLT(b)); - context->rectangle (0, 0, width, height); - context->fill (); - - double usable_width = width - pos_box_size; - - /* compute the centers of the L/R boxes based on the current stereo width */ - - if (fmod (usable_width,2.0) == 0) { - /* even width, but we need odd, so that there is an exact center. - So, offset cairo by 1, and reduce effective width by 1 - */ - usable_width -= 1.0; - context->translate (1.0, 0.0); - } - - const double half_lr_box = lr_box_size/2.0; - double left; - double right; - - left = 4 + half_lr_box; // center of left box - right = width - 4 - half_lr_box; // center of right box - - /* center line */ - context->set_source_rgba (UINT_RGBA_R_FLT(o), UINT_RGBA_G_FLT(o), UINT_RGBA_B_FLT(o), UINT_RGBA_A_FLT(o)); - context->set_line_width (1.0); - context->move_to ((pos_box_size/2.0) + (usable_width/2.0), 0); - context->line_to ((pos_box_size/2.0) + (usable_width/2.0), height); - context->stroke (); - - /* left box */ - - rounded_rectangle (context, - left - half_lr_box, - half_lr_box+step_down, - lr_box_size, lr_box_size, corner_radius); - context->set_source_rgba (UINT_RGBA_R_FLT(o), UINT_RGBA_G_FLT(o), UINT_RGBA_B_FLT(o), UINT_RGBA_A_FLT(o)); - context->stroke_preserve (); - context->set_source_rgba (UINT_RGBA_R_FLT(f), UINT_RGBA_G_FLT(f), UINT_RGBA_B_FLT(f), UINT_RGBA_A_FLT(f)); - context->fill (); - - /* add text */ - - context->move_to ( - left - half_lr_box + 3, - (lr_box_size/2) + step_down + 13); - context->select_font_face ("sans-serif", Cairo::FONT_SLANT_NORMAL, Cairo::FONT_WEIGHT_BOLD); - context->set_source_rgba (UINT_RGBA_R_FLT(t), UINT_RGBA_G_FLT(t), UINT_RGBA_B_FLT(t), UINT_RGBA_A_FLT(t)); - context->show_text (_("L")); - - /* right box */ + Cairo::RefPtr<Cairo::Context> context = get_window()->create_cairo_context(); + + int width, height; + double pos = position_control->get_value (); /* 0..1 */ + uint32_t o, f, t, b, pf, po; + const double corner_radius = 5; + + width = get_width(); + height = get_height (); + + o = colors.outline; + f = colors.fill; + t = colors.text; + b = colors.background; + pf = colors.pos_fill; + po = colors.pos_outline; + + if (_panner_shell->bypassed()) { + b = 0x20202040; + f = 0x404040ff; + o = 0x606060ff; + po = 0x606060ff; + pf = 0x404040ff; + t = 0x606060ff; + } - rounded_rectangle (context, - right - half_lr_box, - half_lr_box+step_down, - lr_box_size, lr_box_size, corner_radius); - context->set_source_rgba (UINT_RGBA_R_FLT(o), UINT_RGBA_G_FLT(o), UINT_RGBA_B_FLT(o), UINT_RGBA_A_FLT(o)); - context->stroke_preserve (); - context->set_source_rgba (UINT_RGBA_R_FLT(f), UINT_RGBA_G_FLT(f), UINT_RGBA_B_FLT(f), UINT_RGBA_A_FLT(f)); + /* background */ + context->set_source_rgba (UINT_RGBA_R_FLT(b), UINT_RGBA_G_FLT(b), UINT_RGBA_B_FLT(b), UINT_RGBA_A_FLT(b)); + context->rectangle (0, 0, width, height); context->fill (); - /* add text */ - - context->move_to ( - right - half_lr_box + 3, - (lr_box_size/2)+step_down + 13); - context->set_source_rgba (UINT_RGBA_R_FLT(t), UINT_RGBA_G_FLT(t), UINT_RGBA_B_FLT(t), UINT_RGBA_A_FLT(t)); - context->show_text (_("R")); - - /* 2 lines that connect them both */ - context->set_source_rgba (UINT_RGBA_R_FLT(o), UINT_RGBA_G_FLT(o), UINT_RGBA_B_FLT(o), UINT_RGBA_A_FLT(o)); - context->set_line_width (1.0); - - /* make the lines a little longer than they need to be, because the corners of - the boxes are rounded and we don't want a gap - */ - context->move_to (left + half_lr_box - corner_radius, half_lr_box+step_down); - context->line_to (right - half_lr_box + corner_radius, half_lr_box+step_down); - context->stroke (); + double usable_width = width - pos_box_size; - context->move_to (left + half_lr_box - corner_radius, half_lr_box+step_down+lr_box_size); - context->line_to (right - half_lr_box + corner_radius, half_lr_box+step_down+lr_box_size); - context->stroke (); - - /* draw the position indicator */ + /* compute the centers of the L/R boxes based on the current stereo width */ + if (fmod (usable_width,2.0) == 0) { + usable_width -= 1.0; + } + const double half_lr_box = lr_box_size/2.0; + const double left = 4 + half_lr_box; // center of left box + const double right = width - 4 - half_lr_box; // center of right box + + /* center line */ + context->set_source_rgba (UINT_RGBA_R_FLT(o), UINT_RGBA_G_FLT(o), UINT_RGBA_B_FLT(o), UINT_RGBA_A_FLT(o)); + context->set_line_width (1.0); + context->move_to ((pos_box_size/2.0) + (usable_width/2.0), 0); + context->line_to ((pos_box_size/2.0) + (usable_width/2.0), height); + context->stroke (); + + context->set_line_width (1.0); + /* left box */ + + rounded_left_half_rectangle (context, + left - half_lr_box + .5, + half_lr_box + step_down, + lr_box_size, lr_box_size, corner_radius); + context->set_source_rgba (UINT_RGBA_R_FLT(f), UINT_RGBA_G_FLT(f), UINT_RGBA_B_FLT(f), UINT_RGBA_A_FLT(f)); + context->fill_preserve (); + context->set_source_rgba (UINT_RGBA_R_FLT(o), UINT_RGBA_G_FLT(o), UINT_RGBA_B_FLT(o), UINT_RGBA_A_FLT(o)); + context->stroke(); + + /* add text */ + int tw, th; + Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(get_pango_context()); + layout->set_attributes (panner_font_attributes); + + layout->set_text (_("L")); + layout->get_pixel_size(tw, th); + context->move_to (rint(left - tw/2), rint(lr_box_size + step_down - th/2)); + context->set_source_rgba (UINT_RGBA_R_FLT(t), UINT_RGBA_G_FLT(t), UINT_RGBA_B_FLT(t), UINT_RGBA_A_FLT(t)); + pango_cairo_show_layout (context->cobj(), layout->gobj()); + + /* right box */ + rounded_right_half_rectangle (context, + right - half_lr_box - .5, + half_lr_box + step_down, + lr_box_size, lr_box_size, corner_radius); + context->set_source_rgba (UINT_RGBA_R_FLT(f), UINT_RGBA_G_FLT(f), UINT_RGBA_B_FLT(f), UINT_RGBA_A_FLT(f)); + context->fill_preserve (); + context->set_source_rgba (UINT_RGBA_R_FLT(o), UINT_RGBA_G_FLT(o), UINT_RGBA_B_FLT(o), UINT_RGBA_A_FLT(o)); + context->stroke(); + + /* add text */ + layout->set_text (_("R")); + layout->get_pixel_size(tw, th); + context->move_to (rint(right - tw/2), rint(lr_box_size + step_down - th/2)); + context->set_source_rgba (UINT_RGBA_R_FLT(t), UINT_RGBA_G_FLT(t), UINT_RGBA_B_FLT(t), UINT_RGBA_A_FLT(t)); + pango_cairo_show_layout (context->cobj(), layout->gobj()); + + /* 2 lines that connect them both */ + context->set_line_width (1.0); + + if (_panner_shell->panner_gui_uri() != "http://ardour.org/plugin/panner_balance#ui") { + context->set_source_rgba (UINT_RGBA_R_FLT(o), UINT_RGBA_G_FLT(o), UINT_RGBA_B_FLT(o), UINT_RGBA_A_FLT(o)); + context->move_to (left + half_lr_box, half_lr_box + step_down); + context->line_to (right - half_lr_box, half_lr_box + step_down); + context->stroke (); + + context->move_to (left + half_lr_box, half_lr_box+step_down+lr_box_size); + context->line_to (right - half_lr_box, half_lr_box+step_down+lr_box_size); + context->stroke (); + } else { + context->move_to (left + half_lr_box, half_lr_box+step_down+lr_box_size); + context->line_to (left + half_lr_box, half_lr_box + step_down); + context->line_to ((pos_box_size/2.0) + (usable_width/2.0), half_lr_box+step_down+lr_box_size); + context->line_to (right - half_lr_box, half_lr_box + step_down); + context->line_to (right - half_lr_box, half_lr_box+step_down+lr_box_size); + context->close_path(); + + context->set_source_rgba (UINT_RGBA_R_FLT(f), UINT_RGBA_G_FLT(f), UINT_RGBA_B_FLT(f), UINT_RGBA_A_FLT(f)); + context->fill_preserve (); + context->set_source_rgba (UINT_RGBA_R_FLT(o), UINT_RGBA_G_FLT(o), UINT_RGBA_B_FLT(o), UINT_RGBA_A_FLT(o)); + context->stroke (); + } - double spos = (pos_box_size/2.0) + (usable_width * pos); + /* draw the position indicator */ + double spos = (pos_box_size/2.0) + (usable_width * pos); - context->set_line_width (2.0); + context->set_line_width (2.0); context->move_to (spos + (pos_box_size/2.0), top_step); /* top right */ - context->rel_line_to (0.0, pos_box_size); /* lower right */ - context->rel_line_to (-pos_box_size/2.0, 4.0); /* bottom point */ - context->rel_line_to (-pos_box_size/2.0, -4.0); /* lower left */ - context->rel_line_to (0.0, -pos_box_size); /* upper left */ - context->close_path (); + context->rel_line_to (0.0, pos_box_size); /* lower right */ + context->rel_line_to (-pos_box_size/2.0, 4.0); /* bottom point */ + context->rel_line_to (-pos_box_size/2.0, -4.0); /* lower left */ + context->rel_line_to (0.0, -pos_box_size); /* upper left */ + context->close_path (); - context->set_source_rgba (UINT_RGBA_R_FLT(po), UINT_RGBA_G_FLT(po), UINT_RGBA_B_FLT(po), UINT_RGBA_A_FLT(po)); - context->stroke_preserve (); - context->set_source_rgba (UINT_RGBA_R_FLT(pf), UINT_RGBA_G_FLT(pf), UINT_RGBA_B_FLT(pf), UINT_RGBA_A_FLT(pf)); + context->set_source_rgba (UINT_RGBA_R_FLT(po), UINT_RGBA_G_FLT(po), UINT_RGBA_B_FLT(po), UINT_RGBA_A_FLT(po)); + context->stroke_preserve (); + context->set_source_rgba (UINT_RGBA_R_FLT(pf), UINT_RGBA_G_FLT(pf), UINT_RGBA_B_FLT(pf), UINT_RGBA_A_FLT(pf)); context->fill (); - /* marker line */ - - context->set_line_width (1.0); - context->move_to (spos, pos_box_size+4); - context->rel_line_to (0, half_lr_box+step_down); - context->set_source_rgba (UINT_RGBA_R_FLT(po), UINT_RGBA_G_FLT(po), UINT_RGBA_B_FLT(po), UINT_RGBA_A_FLT(po)); - context->stroke (); + /* marker line */ + context->set_line_width (1.0); + context->move_to (spos, pos_box_size + 5); + context->rel_line_to (0, half_lr_box+step_down); + context->set_source_rgba (UINT_RGBA_R_FLT(po), UINT_RGBA_G_FLT(po), UINT_RGBA_B_FLT(po), UINT_RGBA_A_FLT(po)); + context->stroke (); - /* done */ + /* done */ return true; } @@ -250,62 +281,65 @@ MonoPanner::on_button_press_event (GdkEventButton* ev) if (PannerInterface::on_button_press_event (ev)) { return true; } - - drag_start_x = ev->x; - last_drag_x = ev->x; + if (_panner_shell->bypassed()) { + return false; + } - _dragging = false; + drag_start_x = ev->x; + last_drag_x = ev->x; + + _dragging = false; _tooltip.target_stop_drag (); - accumulated_delta = 0; - detented = false; + accumulated_delta = 0; + detented = false; - /* Let the binding proxies get first crack at the press event - */ + /* Let the binding proxies get first crack at the press event + */ - if (ev->y < 20) { - if (position_binder.button_press_handler (ev)) { - return true; - } - } + if (ev->y < 20) { + if (position_binder.button_press_handler (ev)) { + return true; + } + } - if (ev->button != 1) { - return false; - } + if (ev->button != 1) { + return false; + } - if (ev->type == GDK_2BUTTON_PRESS) { - int width = get_width(); + if (ev->type == GDK_2BUTTON_PRESS) { + int width = get_width(); - if (Keyboard::modifier_state_contains (ev->state, Keyboard::TertiaryModifier)) { - /* handled by button release */ - return true; - } + if (Keyboard::modifier_state_contains (ev->state, Keyboard::TertiaryModifier)) { + /* handled by button release */ + return true; + } - if (ev->x <= width/3) { - /* left side dbl click */ - position_control->set_value (0); - } else if (ev->x > 2*width/3) { - position_control->set_value (1.0); - } else { - position_control->set_value (0.5); - } + if (ev->x <= width/3) { + /* left side dbl click */ + position_control->set_value (0); + } else if (ev->x > 2*width/3) { + position_control->set_value (1.0); + } else { + position_control->set_value (0.5); + } - _dragging = false; + _dragging = false; _tooltip.target_stop_drag (); - } else if (ev->type == GDK_BUTTON_PRESS) { + } else if (ev->type == GDK_BUTTON_PRESS) { - if (Keyboard::modifier_state_contains (ev->state, Keyboard::TertiaryModifier)) { - /* handled by button release */ - return true; - } + if (Keyboard::modifier_state_contains (ev->state, Keyboard::TertiaryModifier)) { + /* handled by button release */ + return true; + } - _dragging = true; + _dragging = true; _tooltip.target_start_drag (); - StartGesture (); - } + StartGesture (); + } - return true; + return true; } bool @@ -315,121 +349,136 @@ MonoPanner::on_button_release_event (GdkEventButton* ev) return true; } - if (ev->button != 1) { - return false; - } + if (ev->button != 1) { + return false; + } - _dragging = false; + if (_panner_shell->bypassed()) { + return false; + } + + _dragging = false; _tooltip.target_stop_drag (); - accumulated_delta = 0; - detented = false; + accumulated_delta = 0; + detented = false; - if (Keyboard::modifier_state_contains (ev->state, Keyboard::TertiaryModifier)) { + if (Keyboard::modifier_state_contains (ev->state, Keyboard::TertiaryModifier)) { _panner->reset (); - } else { - StopGesture (); - } + } else { + StopGesture (); + } - return true; + return true; } bool MonoPanner::on_scroll_event (GdkEventScroll* ev) { - double one_degree = 1.0/180.0; // one degree as a number from 0..1, since 180 degrees is the full L/R axis - double pv = position_control->get_value(); // 0..1.0 ; 0 = left - double step; - - if (Keyboard::modifier_state_contains (ev->state, Keyboard::PrimaryModifier)) { - step = one_degree; - } else { - step = one_degree * 5.0; - } - - switch (ev->direction) { - case GDK_SCROLL_UP: - case GDK_SCROLL_LEFT: - pv -= step; - position_control->set_value (pv); - break; - case GDK_SCROLL_DOWN: - case GDK_SCROLL_RIGHT: - pv += step; - position_control->set_value (pv); - break; - } - - return true; + double one_degree = 1.0/180.0; // one degree as a number from 0..1, since 180 degrees is the full L/R axis + double pv = position_control->get_value(); // 0..1.0 ; 0 = left + double step; + + if (_panner_shell->bypassed()) { + return false; + } + + if (Keyboard::modifier_state_contains (ev->state, Keyboard::PrimaryModifier)) { + step = one_degree; + } else { + step = one_degree * 5.0; + } + + switch (ev->direction) { + case GDK_SCROLL_UP: + case GDK_SCROLL_LEFT: + pv -= step; + position_control->set_value (pv); + break; + case GDK_SCROLL_DOWN: + case GDK_SCROLL_RIGHT: + pv += step; + position_control->set_value (pv); + break; + } + + return true; } bool MonoPanner::on_motion_notify_event (GdkEventMotion* ev) { - if (!_dragging) { - return false; - } - - int w = get_width(); - double delta = (ev->x - last_drag_x) / (double) w; - - /* create a detent close to the center */ - - if (!detented && ARDOUR::Panner::equivalent (position_control->get_value(), 0.5)) { - detented = true; - /* snap to center */ - position_control->set_value (0.5); - } - - if (detented) { - accumulated_delta += delta; - - /* have we pulled far enough to escape ? */ - - if (fabs (accumulated_delta) >= 0.025) { - position_control->set_value (position_control->get_value() + accumulated_delta); - detented = false; - accumulated_delta = false; - } - } else { - double pv = position_control->get_value(); // 0..1.0 ; 0 = left - position_control->set_value (pv + delta); - } - - last_drag_x = ev->x; - return true; + if (_panner_shell->bypassed()) { + _dragging = false; + } + if (!_dragging) { + return false; + } + + int w = get_width(); + double delta = (ev->x - last_drag_x) / (double) w; + + /* create a detent close to the center */ + + if (!detented && ARDOUR::Panner::equivalent (position_control->get_value(), 0.5)) { + detented = true; + /* snap to center */ + position_control->set_value (0.5); + } + + if (detented) { + accumulated_delta += delta; + + /* have we pulled far enough to escape ? */ + + if (fabs (accumulated_delta) >= 0.025) { + position_control->set_value (position_control->get_value() + accumulated_delta); + detented = false; + accumulated_delta = false; + } + } else { + double pv = position_control->get_value(); // 0..1.0 ; 0 = left + position_control->set_value (pv + delta); + } + + last_drag_x = ev->x; + return true; } bool MonoPanner::on_key_press_event (GdkEventKey* ev) { - double one_degree = 1.0/180.0; - double pv = position_control->get_value(); // 0..1.0 ; 0 = left - double step; - - if (Keyboard::modifier_state_contains (ev->state, Keyboard::PrimaryModifier)) { - step = one_degree; - } else { - step = one_degree * 5.0; - } - - switch (ev->keyval) { - case GDK_Left: - pv -= step; - position_control->set_value (pv); - break; - case GDK_Right: - pv += step; - position_control->set_value (pv); - break; - case GDK_0: - case GDK_KP_0: - position_control->set_value (0.0); - break; - default: - return false; - } - - return true; + double one_degree = 1.0/180.0; + double pv = position_control->get_value(); // 0..1.0 ; 0 = left + double step; + + if (_panner_shell->bypassed()) { + return false; + } + + if (Keyboard::modifier_state_contains (ev->state, Keyboard::PrimaryModifier)) { + step = one_degree; + } else { + step = one_degree * 5.0; + } + + switch (ev->keyval) { + case GDK_Left: + pv -= step; + position_control->set_value (pv); + break; + case GDK_Right: + pv += step; + position_control->set_value (pv); + break; + case GDK_0: + case GDK_KP_0: + position_control->set_value (0.0); + break; + default: + return false; + } + + return true; } void @@ -450,6 +499,12 @@ MonoPanner::color_handler () queue_draw (); } +void +MonoPanner::bypass_handler () +{ + queue_draw (); +} + PannerEditor* MonoPanner::editor () { diff --git a/gtk2_ardour/mono_panner.h b/gtk2_ardour/mono_panner.h index 1c387ad32c..b79038bab7 100644 --- a/gtk2_ardour/mono_panner.h +++ b/gtk2_ardour/mono_panner.h @@ -28,6 +28,10 @@ #include "panner_interface.h" +namespace ARDOUR { + class PannerShell; +} + namespace PBD { class Controllable; } @@ -35,7 +39,7 @@ namespace PBD { class MonoPanner : public PannerInterface { public: - MonoPanner (boost::shared_ptr<ARDOUR::Panner>); + MonoPanner (boost::shared_ptr<ARDOUR::PannerShell>); ~MonoPanner (); boost::shared_ptr<PBD::Controllable> get_controllable() const { return position_control; } @@ -53,6 +57,7 @@ class MonoPanner : public PannerInterface private: PannerEditor* editor (); + boost::shared_ptr<ARDOUR::PannerShell> _panner_shell; boost::shared_ptr<PBD::Controllable> position_control; PBD::ScopedConnectionList connections; @@ -76,10 +81,14 @@ class MonoPanner : public PannerInterface bool _dragging; + static Pango::AttrList panner_font_attributes; + static bool have_font; + static ColorScheme colors; static void set_colors (); static bool have_colors; void color_handler (); + void bypass_handler (); }; #endif /* __gtk_ardour_mono_panner_h__ */ diff --git a/gtk2_ardour/panner_ui.cc b/gtk2_ardour/panner_ui.cc index c82a44f399..3ee794e578 100644 --- a/gtk2_ardour/panner_ui.cc +++ b/gtk2_ardour/panner_ui.cc @@ -51,6 +51,7 @@ PannerUI::PannerUI (Session* s) , _current_nins (-1) , pan_automation_style_button ("") , pan_automation_state_button ("") + , _panner_list() { set_session (s); @@ -203,7 +204,7 @@ PannerUI::~PannerUI () void PannerUI::panshell_changed () { - set_panner (_panshell, _panshell->panner()); + set_panner (_panshell, _panshell->panner()); setup_pan (); } @@ -233,73 +234,51 @@ PannerUI::setup_pan () return; } - if (nouts == 0 || nouts == 1) { + if (_panshell->panner_gui_uri() == "http://ardour.org/plugin/panner_2in2out#ui") + { + boost::shared_ptr<Pannable> pannable = _panner->pannable(); - /* stick something into the panning viewport so that it redraws */ - - EventBox* eb = manage (new EventBox()); - pan_vbox.pack_start (*eb, false, false); - - delete big_window; - big_window = 0; - - } else if (nouts == 2) { - - if (nins == 2) { - - /* add integrated 2in/2out panner GUI */ - - boost::shared_ptr<Pannable> pannable = _panner->pannable(); - - _stereo_panner = new StereoPanner (_panner); - _stereo_panner->set_size_request (-1, pan_bar_height); - pan_vbox.pack_start (*_stereo_panner, false, false); - - boost::shared_ptr<AutomationControl> ac; + _stereo_panner = new StereoPanner (_panshell); + _stereo_panner->set_size_request (-1, pan_bar_height); + pan_vbox.pack_start (*_stereo_panner, false, false); - ac = pannable->pan_azimuth_control; - _stereo_panner->StartPositionGesture.connect (sigc::bind (sigc::mem_fun (*this, &PannerUI::start_touch), - boost::weak_ptr<AutomationControl> (ac))); - _stereo_panner->StopPositionGesture.connect (sigc::bind (sigc::mem_fun (*this, &PannerUI::stop_touch), - boost::weak_ptr<AutomationControl>(ac))); + boost::shared_ptr<AutomationControl> ac; - ac = pannable->pan_width_control; - _stereo_panner->StartWidthGesture.connect (sigc::bind (sigc::mem_fun (*this, &PannerUI::start_touch), - boost::weak_ptr<AutomationControl> (ac))); - _stereo_panner->StopWidthGesture.connect (sigc::bind (sigc::mem_fun (*this, &PannerUI::stop_touch), - boost::weak_ptr<AutomationControl>(ac))); - _stereo_panner->signal_button_release_event().connect (sigc::mem_fun(*this, &PannerUI::pan_button_event)); + ac = pannable->pan_azimuth_control; + _stereo_panner->StartPositionGesture.connect (sigc::bind (sigc::mem_fun (*this, &PannerUI::start_touch), + boost::weak_ptr<AutomationControl> (ac))); + _stereo_panner->StopPositionGesture.connect (sigc::bind (sigc::mem_fun (*this, &PannerUI::stop_touch), + boost::weak_ptr<AutomationControl>(ac))); - } else if (nins == 1) { - /* 1-in/2out */ - - boost::shared_ptr<Pannable> pannable = _panner->pannable(); - boost::shared_ptr<AutomationControl> ac = pannable->pan_azimuth_control; - - _mono_panner = new MonoPanner (_panner); - - _mono_panner->StartGesture.connect (sigc::bind (sigc::mem_fun (*this, &PannerUI::start_touch), - boost::weak_ptr<AutomationControl> (ac))); - _mono_panner->StopGesture.connect (sigc::bind (sigc::mem_fun (*this, &PannerUI::stop_touch), - boost::weak_ptr<AutomationControl>(ac))); - - _mono_panner->signal_button_release_event().connect (sigc::mem_fun(*this, &PannerUI::pan_button_event)); - - _mono_panner->set_size_request (-1, pan_bar_height); + ac = pannable->pan_width_control; + _stereo_panner->StartWidthGesture.connect (sigc::bind (sigc::mem_fun (*this, &PannerUI::start_touch), + boost::weak_ptr<AutomationControl> (ac))); + _stereo_panner->StopWidthGesture.connect (sigc::bind (sigc::mem_fun (*this, &PannerUI::stop_touch), + boost::weak_ptr<AutomationControl>(ac))); + _stereo_panner->signal_button_release_event().connect (sigc::mem_fun(*this, &PannerUI::pan_button_event)); + } + else if (_panshell->panner_gui_uri() == "http://ardour.org/plugin/panner_1in2out#ui" + || _panshell->panner_gui_uri() == "http://ardour.org/plugin/panner_balance#ui") + { + boost::shared_ptr<Pannable> pannable = _panner->pannable(); + boost::shared_ptr<AutomationControl> ac = pannable->pan_azimuth_control; - update_pan_sensitive (); - pan_vbox.pack_start (*_mono_panner, false, false); + _mono_panner = new MonoPanner (_panshell); - } else { - warning << string_compose (_("No panner user interface is currently available for %1-in/2out tracks/busses"), - nins) << endmsg; - } + _mono_panner->StartGesture.connect (sigc::bind (sigc::mem_fun (*this, &PannerUI::start_touch), + boost::weak_ptr<AutomationControl> (ac))); + _mono_panner->StopGesture.connect (sigc::bind (sigc::mem_fun (*this, &PannerUI::stop_touch), + boost::weak_ptr<AutomationControl>(ac))); - delete big_window; - big_window = 0; + _mono_panner->signal_button_release_event().connect (sigc::mem_fun(*this, &PannerUI::pan_button_event)); - } else { + _mono_panner->set_size_request (-1, pan_bar_height); + update_pan_sensitive (); + pan_vbox.pack_start (*_mono_panner, false, false); + } + else if (_panshell->panner_gui_uri() == "http://ardour.org/plugin/panner_vbap#ui") + { if (!twod_panner) { twod_panner = new Panner2d (_panshell, 61); twod_panner->set_name ("MixerPanZone"); @@ -309,17 +288,26 @@ PannerUI::setup_pan () update_pan_sensitive (); twod_panner->reset (nins); - if (big_window) { - big_window->reset (nins); - } + if (big_window) { + big_window->reset (nins); + } twod_panner->set_size_request (-1, 61); /* and finally, add it to the panner frame */ - pan_vbox.pack_start (*twod_panner, false, false); + pan_vbox.pack_start (*twod_panner, false, false); + } + else + { + /* stick something into the panning viewport so that it redraws */ + EventBox* eb = manage (new EventBox()); + pan_vbox.pack_start (*eb, false, false); + + delete big_window; + big_window = 0; } - pan_vbox.show_all (); + pan_vbox.show_all (); } void @@ -388,8 +376,27 @@ PannerUI::build_pan_menu () bypass_menu_item->set_active (_panshell->bypassed()); bypass_menu_item->signal_toggled().connect (sigc::mem_fun(*this, &PannerUI::pan_bypass_toggle)); - items.push_back (MenuElem (_("Reset"), sigc::mem_fun (*this, &PannerUI::pan_reset))); - items.push_back (MenuElem (_("Edit..."), sigc::mem_fun (*this, &PannerUI::pan_edit))); + if (!_panshell->bypassed()) { + items.push_back (MenuElem (_("Reset"), sigc::mem_fun (*this, &PannerUI::pan_reset))); + items.push_back (MenuElem (_("Edit..."), sigc::mem_fun (*this, &PannerUI::pan_edit))); + } + + if (_route && _panner_list.size() > 1 && !_panshell->bypassed()) { + RadioMenuItem::Group group; + items.push_back (SeparatorElem()); + + assert(_panshell->user_selected_panner_uri() == "" + || _panshell->user_selected_panner_uri() == _panshell->current_panner_uri()); + + _suspend_menu_callbacks = true; + for (std::map<std::string,std::string>::const_iterator p = _panner_list.begin(); p != _panner_list.end(); ++p) { + items.push_back (RadioMenuElem (group, p->second, + sigc::bind(sigc::mem_fun (*this, &PannerUI::pan_set_custom_type), p->first))); + RadioMenuItem* i = dynamic_cast<RadioMenuItem *> (&items.back ()); + i->set_active (_panshell->current_panner_uri() == p->first); + } + _suspend_menu_callbacks = false; + } } void @@ -403,6 +410,9 @@ PannerUI::pan_bypass_toggle () void PannerUI::pan_edit () { + if (_panshell->bypassed()) { + return; + } if (_mono_panner) { _mono_panner->edit (); } else if (_stereo_panner) { @@ -413,10 +423,21 @@ PannerUI::pan_edit () void PannerUI::pan_reset () { + if (_panshell->bypassed()) { + return; + } _panner->reset (); } void +PannerUI::pan_set_custom_type (std::string uri) { + if (_suspend_menu_callbacks) return; + if (_route) { + _route->set_custom_panner_uri(uri); + } +} + +void PannerUI::effective_pan_display () { if (_stereo_panner) { @@ -609,3 +630,10 @@ void PannerUI::position_adjusted () { } + +void +PannerUI::set_available_panners(boost::shared_ptr<ARDOUR::Route> r, std::map<std::string,std::string> p) +{ + _route = r; + _panner_list = p; +} diff --git a/gtk2_ardour/panner_ui.h b/gtk2_ardour/panner_ui.h index de93d49956..dca24451d1 100644 --- a/gtk2_ardour/panner_ui.h +++ b/gtk2_ardour/panner_ui.h @@ -73,6 +73,7 @@ class PannerUI : public Gtk::HBox, public ARDOUR::SessionHandlePtr void set_width (Width); void setup_pan (); + void set_available_panners(boost::shared_ptr<ARDOUR::Route>, std::map<std::string,std::string>); void effective_pan_display (); @@ -141,6 +142,7 @@ class PannerUI : public Gtk::HBox, public ARDOUR::SessionHandlePtr void pan_reset (); void pan_bypass_toggle (); void pan_edit (); + void pan_set_custom_type (std::string type); void pan_automation_state_changed(); void pan_automation_style_changed(); @@ -158,6 +160,10 @@ class PannerUI : public Gtk::HBox, public ARDOUR::SessionHandlePtr void start_touch (boost::weak_ptr<ARDOUR::AutomationControl>); void stop_touch (boost::weak_ptr<ARDOUR::AutomationControl>); + + boost::shared_ptr<ARDOUR::Route> _route; + std::map<std::string,std::string> _panner_list; + bool _suspend_menu_callbacks; }; #endif /* __ardour_gtk_panner_ui_h__ */ diff --git a/gtk2_ardour/processor_box.cc b/gtk2_ardour/processor_box.cc index daab501daa..cd91589391 100644 --- a/gtk2_ardour/processor_box.cc +++ b/gtk2_ardour/processor_box.cc @@ -297,12 +297,17 @@ ProcessorEntry::setup_tooltip () if (_processor) { boost::shared_ptr<PluginInsert> pi = boost::dynamic_pointer_cast<PluginInsert> (_processor); if (pi) { + std::string postfix = ""; + uint32_t replicated; + if ((replicated = pi->get_count()) > 1) { + postfix = string_compose(_("\nThis mono plugin has been replicated %1 times."), replicated); + } if (pi->plugin()->has_editor()) { ARDOUR_UI::instance()->set_tip (_button, - string_compose (_("<b>%1</b>\nDouble-click to show GUI.\nAlt+double-click to show generic GUI."), name (Wide))); + string_compose (_("<b>%1</b>\nDouble-click to show GUI.\nAlt+double-click to show generic GUI.%2"), name (Wide), postfix)); } else { ARDOUR_UI::instance()->set_tip (_button, - string_compose (_("<b>%1</b>\nDouble-click to show generic GUI."), name (Wide))); + string_compose (_("<b>%1</b>\nDouble-click to show generic GUI.%2"), name (Wide), postfix)); } return; } @@ -341,6 +346,13 @@ ProcessorEntry::name (Width w) const } } else { + boost::shared_ptr<ARDOUR::PluginInsert> pi; + uint32_t replicated; + if ((pi = boost::dynamic_pointer_cast<ARDOUR::PluginInsert> (_processor)) != 0 + && (replicated = pi->get_count()) > 1) + { + name_display += string_compose(_("(%1x1) "), replicated); + } switch (w) { case Wide: @@ -706,9 +718,6 @@ ProcessorEntry::PortIcon::on_expose_event (GdkEventExpose* ev) cairo_rectangle (cr, ev->area.x, ev->area.y, ev->area.width, ev->area.height); cairo_clip (cr); - cairo_set_line_width (cr, 5.0); - cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); - Gtk::Allocation a = get_allocation(); double const width = a.get_width(); double const height = a.get_height(); @@ -719,8 +728,6 @@ ProcessorEntry::PortIcon::on_expose_event (GdkEventExpose* ev) cairo_rectangle (cr, 0, 0, width, height); cairo_fill (cr); - const double y0 = _input ? height-.5 : .5; - if (_ports.n_total() > 1) { for (uint32_t i = 0; i < _ports.n_total(); ++i) { if (i < _ports.n_midi()) { @@ -734,10 +741,9 @@ ProcessorEntry::PortIcon::on_expose_event (GdkEventExpose* ev) UINT_RGBA_G_FLT(audio_port_color), UINT_RGBA_B_FLT(audio_port_color)); } - const float x = rintf(width * (.2f + .6f * i / (_ports.n_total() - 1.f))) + .5f; - cairo_move_to (cr, x, y0); - cairo_close_path(cr); - cairo_stroke(cr); + const float x = rintf(width * (.2f + .6f * i / (_ports.n_total() - 1.f))); + cairo_rectangle (cr, x-1, 0, 3, height); + cairo_fill(cr); } } else if (_ports.n_total() == 1) { if (_ports.n_midi() == 1) { @@ -751,8 +757,9 @@ ProcessorEntry::PortIcon::on_expose_event (GdkEventExpose* ev) UINT_RGBA_G_FLT(audio_port_color), UINT_RGBA_B_FLT(audio_port_color)); } - cairo_move_to (cr, rintf(width * .5) + .5f, y0); - cairo_close_path(cr); + const float x = rintf(width * .5); + cairo_rectangle (cr, x-1, 0, 3, height); + cairo_fill(cr); cairo_stroke(cr); } @@ -797,7 +804,7 @@ ProcessorEntry::RoutingIcon::on_expose_event (GdkEventExpose* ev) UINT_RGBA_B_FLT(midi_port_color)); if (midi_sources > 0 && midi_sinks > 0 && sinks > 1 && sources > 1) { for (uint32_t i = 0 ; i < midi_sources; ++i) { - const float si_x = rintf(width * (.2f + .6f * i / (sinks - 1.f))) + .5f; + const float si_x = rintf(width * (.2f + .6f * i / (sinks - 1.f))) + .5f; const float si_x0 = rintf(width * (.2f + .6f * i / (sources - 1.f))) + .5f; cairo_move_to (cr, si_x, height); cairo_curve_to (cr, si_x, 0, si_x0, height, si_x0, 0); diff --git a/gtk2_ardour/processor_box.h b/gtk2_ardour/processor_box.h index d25710392e..a66a6c4a56 100644 --- a/gtk2_ardour/processor_box.h +++ b/gtk2_ardour/processor_box.h @@ -211,7 +211,7 @@ private: PortIcon(bool input) { _input = input; _ports = ARDOUR::ChanCount(ARDOUR::DataType::AUDIO, 1); - set_size_request (-1, 3); + set_size_request (-1, 2); } void set_ports(ARDOUR::ChanCount const ports) { _ports = ports; } private: diff --git a/gtk2_ardour/stereo_panner.cc b/gtk2_ardour/stereo_panner.cc index 4e5c6de959..e650338af4 100644 --- a/gtk2_ardour/stereo_panner.cc +++ b/gtk2_ardour/stereo_panner.cc @@ -22,6 +22,7 @@ #include <cmath> #include <gtkmm/window.h> +#include <pangomm/layout.h> #include "pbd/controllable.h" #include "pbd/compose.h" @@ -34,6 +35,7 @@ #include "ardour/pannable.h" #include "ardour/panner.h" +#include "ardour/panner_shell.h" #include "ardour_ui.h" #include "global_signals.h" @@ -56,10 +58,14 @@ static const int top_step = 2; StereoPanner::ColorScheme StereoPanner::colors[3]; bool StereoPanner::have_colors = false; +Pango::AttrList StereoPanner::panner_font_attributes; +bool StereoPanner::have_font = false; + using namespace ARDOUR; -StereoPanner::StereoPanner (boost::shared_ptr<Panner> panner) - : PannerInterface (panner) +StereoPanner::StereoPanner (boost::shared_ptr<PannerShell> p) + : PannerInterface (p->panner()) + , _panner_shell (p) , position_control (_panner->pannable()->pan_azimuth_control) , width_control (_panner->pannable()->pan_width_control) , dragging_position (false) @@ -77,9 +83,21 @@ StereoPanner::StereoPanner (boost::shared_ptr<Panner> panner) set_colors (); have_colors = true; } + if (!have_font) { + Pango::FontDescription font; + Pango::AttrFontDesc* font_attr; + font = Pango::FontDescription ("ArdourMono"); + font.set_weight (Pango::WEIGHT_BOLD); + font.set_size(9 * PANGO_SCALE); + font_attr = new Pango::AttrFontDesc (Pango::Attribute::create_attr_font_desc (font)); + panner_font_attributes.change(*font_attr); + delete font_attr; + have_font = true; + } position_control->Changed.connect (connections, invalidator(*this), boost::bind (&StereoPanner::value_change, this), gui_context()); width_control->Changed.connect (connections, invalidator(*this), boost::bind (&StereoPanner::value_change, this), gui_context()); + _panner_shell->Changed.connect (connections, invalidator (*this), boost::bind (&StereoPanner::bypass_handler, this), gui_context()); ColorsChanged.connect (sigc::mem_fun (*this, &StereoPanner::color_handler)); @@ -94,6 +112,10 @@ StereoPanner::~StereoPanner () void StereoPanner::set_tooltip () { + if (_panner_shell->bypassed()) { + _tooltip.set_tip (_("bypassed")); + return; + } double pos = position_control->get_value(); // 0..1 /* We show the position of the center of the image relative to the left & right. @@ -117,14 +139,17 @@ StereoPanner::on_expose_event (GdkEventExpose*) Glib::RefPtr<Gdk::Window> win (get_window()); Glib::RefPtr<Gdk::GC> gc (get_style()->get_base_gc (get_state())); Cairo::RefPtr<Cairo::Context> context = get_window()->create_cairo_context(); + Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(get_pango_context()); + layout->set_attributes (panner_font_attributes); + int tw, th; int width, height; - double pos = position_control->get_value (); /* 0..1 */ - double swidth = width_control->get_value (); /* -1..+1 */ - double fswidth = fabs (swidth); + const double pos = position_control->get_value (); /* 0..1 */ + const double swidth = width_control->get_value (); /* -1..+1 */ + const double fswidth = fabs (swidth); + const double corner_radius = 5.0; uint32_t o, f, t, b, r; State state; - const double corner_radius = 5.0; width = get_width(); height = get_height (); @@ -143,11 +168,20 @@ StereoPanner::on_expose_event (GdkEventExpose*) b = colors[state].background; r = colors[state].rule; + if (_panner_shell->bypassed()) { + b = 0x20202040; + f = 0x404040ff; + o = 0x606060ff; + t = 0x606060ff; + r = 0x606060ff; + } + /* background */ context->set_source_rgba (UINT_RGBA_R_FLT(b), UINT_RGBA_G_FLT(b), UINT_RGBA_B_FLT(b), UINT_RGBA_A_FLT(b)); cairo_rectangle (context->cobj(), 0, 0, width, height); - context->fill (); + context->fill_preserve (); + context->clip(); /* the usable width is reduced from the real width, because we need space for the two halves of LR boxes that will extend past the actual left/right @@ -166,17 +200,13 @@ StereoPanner::on_expose_event (GdkEventExpose*) context->translate (1.0, 0.0); } - double center = (lr_box_size/2.0) + (usable_width * pos); - const double pan_spread = (fswidth * usable_width)/2.0; const double half_lr_box = lr_box_size/2.0; - int left; - int right; - - left = center - pan_spread; // center of left box - right = center + pan_spread; // center of right box + const double center = rint(half_lr_box + (usable_width * pos)); + const double pan_spread = rint((fswidth * (usable_width-1.0))/2.0); + const double left = center - pan_spread; + const double right = center + pan_spread; /* center line */ - context->set_line_width (1.0); context->move_to ((usable_width + lr_box_size)/2.0, 0); context->rel_line_to (0, height); @@ -184,67 +214,64 @@ StereoPanner::on_expose_event (GdkEventExpose*) context->stroke (); /* compute & draw the line through the box */ - context->set_line_width (2); context->set_source_rgba (UINT_RGBA_R_FLT(o), UINT_RGBA_G_FLT(o), UINT_RGBA_B_FLT(o), UINT_RGBA_A_FLT(o)); - context->move_to (left, top_step+(pos_box_size/2.0)+step_down); - context->line_to (left, top_step+(pos_box_size/2.0)); - context->line_to (right, top_step+(pos_box_size/2.0)); - context->line_to (right, top_step+(pos_box_size/2.0) + step_down); + context->move_to (left, top_step + (pos_box_size/2.0) + step_down + 1.0); + context->line_to (left, top_step + (pos_box_size/2.0)); + context->line_to (right, top_step + (pos_box_size/2.0)); + context->line_to (right, top_step + (pos_box_size/2.0) + step_down + 1.0); context->stroke (); - /* left box */ - - rounded_rectangle (context, left - half_lr_box, - half_lr_box+step_down, - lr_box_size, lr_box_size, corner_radius); - context->set_source_rgba (UINT_RGBA_R_FLT(o), UINT_RGBA_G_FLT(o), UINT_RGBA_B_FLT(o), UINT_RGBA_A_FLT(o)); - context->stroke_preserve (); - context->set_source_rgba (UINT_RGBA_R_FLT(f), UINT_RGBA_G_FLT(f), UINT_RGBA_B_FLT(f), UINT_RGBA_A_FLT(f)); - context->fill (); - - /* add text */ - - context->move_to (left - half_lr_box + 3, - (lr_box_size/2) + step_down + 13); - context->select_font_face ("sans-serif", Cairo::FONT_SLANT_NORMAL, Cairo::FONT_WEIGHT_BOLD); + context->set_line_width (1.0); + /* left box */ if (state != Mono) { + rounded_rectangle (context, left - half_lr_box, + half_lr_box+step_down, + lr_box_size, lr_box_size, corner_radius); + context->set_source_rgba (UINT_RGBA_R_FLT(f), UINT_RGBA_G_FLT(f), UINT_RGBA_B_FLT(f), UINT_RGBA_A_FLT(f)); + context->fill_preserve(); + context->set_source_rgba (UINT_RGBA_R_FLT(o), UINT_RGBA_G_FLT(o), UINT_RGBA_B_FLT(o), UINT_RGBA_A_FLT(o)); + context->stroke(); + + /* add text */ context->set_source_rgba (UINT_RGBA_R_FLT(t), UINT_RGBA_G_FLT(t), UINT_RGBA_B_FLT(t), UINT_RGBA_A_FLT(t)); if (swidth < 0.0) { - context->show_text (_("R")); + layout->set_text (_("R")); } else { - context->show_text (_("L")); + layout->set_text (_("L")); } + layout->get_pixel_size(tw, th); + context->move_to (rint(left - tw/2), rint(lr_box_size + step_down - th/2)); + pango_cairo_show_layout (context->cobj(), layout->gobj()); } /* right box */ - rounded_rectangle (context, right - half_lr_box, - half_lr_box+step_down, - lr_box_size, lr_box_size, corner_radius); - context->set_source_rgba (UINT_RGBA_R_FLT(o), UINT_RGBA_G_FLT(o), UINT_RGBA_B_FLT(o), UINT_RGBA_A_FLT(o)); - context->stroke_preserve (); + half_lr_box+step_down, + lr_box_size, lr_box_size, corner_radius); context->set_source_rgba (UINT_RGBA_R_FLT(f), UINT_RGBA_G_FLT(f), UINT_RGBA_B_FLT(f), UINT_RGBA_A_FLT(f)); - context->fill (); + context->fill_preserve(); + context->set_source_rgba (UINT_RGBA_R_FLT(o), UINT_RGBA_G_FLT(o), UINT_RGBA_B_FLT(o), UINT_RGBA_A_FLT(o)); + context->stroke(); /* add text */ - - context->move_to (right - half_lr_box + 3, (lr_box_size/2)+step_down + 13); context->set_source_rgba (UINT_RGBA_R_FLT(t), UINT_RGBA_G_FLT(t), UINT_RGBA_B_FLT(t), UINT_RGBA_A_FLT(t)); if (state == Mono) { - context->show_text (_("M")); + layout->set_text (_("M")); } else { if (swidth < 0.0) { - context->show_text (_("L")); + layout->set_text (_("L")); } else { - context->show_text (_("R")); + layout->set_text (_("R")); } } + layout->get_pixel_size(tw, th); + context->move_to (rint(right - tw/2), rint(lr_box_size + step_down - th/2)); + pango_cairo_show_layout (context->cobj(), layout->gobj()); /* draw the central box */ - context->set_line_width (2.0); context->move_to (center + (pos_box_size/2.0), top_step); /* top right */ context->rel_line_to (0.0, pos_box_size); /* lower right */ @@ -267,6 +294,10 @@ StereoPanner::on_button_press_event (GdkEventButton* ev) if (PannerInterface::on_button_press_event (ev)) { return true; } + + if (_panner_shell->bypassed()) { + return true; + } drag_start_x = ev->x; last_drag_x = ev->x; @@ -412,6 +443,10 @@ StereoPanner::on_button_release_event (GdkEventButton* ev) return false; } + if (_panner_shell->bypassed()) { + return false; + } + bool const dp = dragging_position; _dragging = false; @@ -443,6 +478,10 @@ StereoPanner::on_scroll_event (GdkEventScroll* ev) double wv = width_control->get_value(); // 0..1.0 ; 0 = left double step; + if (_panner_shell->bypassed()) { + return false; + } + if (Keyboard::modifier_state_contains (ev->state, Keyboard::PrimaryModifier)) { step = one_degree; } else { @@ -474,6 +513,9 @@ StereoPanner::on_scroll_event (GdkEventScroll* ev) bool StereoPanner::on_motion_notify_event (GdkEventMotion* ev) { + if (_panner_shell->bypassed()) { + _dragging = false; + } if (!_dragging) { return false; } @@ -566,6 +608,10 @@ StereoPanner::on_key_press_event (GdkEventKey* ev) double wv = width_control->get_value(); // 0..1.0 ; 0 = left double step; + if (_panner_shell->bypassed()) { + return false; + } + if (Keyboard::modifier_state_contains (ev->state, Keyboard::PrimaryModifier)) { step = one_degree; } else { @@ -641,6 +687,12 @@ StereoPanner::color_handler () queue_draw (); } +void +StereoPanner::bypass_handler () +{ + queue_draw (); +} + PannerEditor* StereoPanner::editor () { diff --git a/gtk2_ardour/stereo_panner.h b/gtk2_ardour/stereo_panner.h index 8b62b7d82a..5ecf343ab1 100644 --- a/gtk2_ardour/stereo_panner.h +++ b/gtk2_ardour/stereo_panner.h @@ -24,6 +24,10 @@ #include "gtkmm2ext/binding_proxy.h" #include "panner_interface.h" +namespace ARDOUR { + class PannerShell; +} + namespace PBD { class Controllable; } @@ -35,7 +39,7 @@ namespace ARDOUR { class StereoPanner : public PannerInterface { public: - StereoPanner (boost::shared_ptr<ARDOUR::Panner>); + StereoPanner (boost::shared_ptr<ARDOUR::PannerShell>); ~StereoPanner (); boost::shared_ptr<PBD::Controllable> get_position_controllable() const { return position_control; } @@ -56,6 +60,7 @@ class StereoPanner : public PannerInterface private: PannerEditor* editor (); + boost::shared_ptr<ARDOUR::PannerShell> _panner_shell; boost::shared_ptr<PBD::Controllable> position_control; boost::shared_ptr<PBD::Controllable> width_control; @@ -90,10 +95,14 @@ class StereoPanner : public PannerInterface bool _dragging; + static Pango::AttrList panner_font_attributes; + static bool have_font; + static ColorScheme colors[3]; static void set_colors (); static bool have_colors; void color_handler (); + void bypass_handler (); }; #endif /* __gtk_ardour_stereo_panner_h__ */ |