summaryrefslogtreecommitdiff
path: root/gtk2_ardour
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2014-01-10 14:53:03 -0500
committerPaul Davis <paul@linuxaudiosystems.com>2014-01-10 14:53:03 -0500
commitd15fda6d751a465d278f477923075d4783f3b1ca (patch)
tree99e36ff934f50d9c980dbeab09ad021cda3d098c /gtk2_ardour
parent22c303d8f6c355a7229eb459cedf4fbdf0eb3c1d (diff)
parent0bdf4c25cfee8cf2408d2b1367f2c5e5c8c509b1 (diff)
fix merge errors with master
Diffstat (limited to 'gtk2_ardour')
-rw-r--r--gtk2_ardour/ardev_common.sh.in2
-rwxr-xr-xgtk2_ardour/artest25
-rw-r--r--gtk2_ardour/mixer_strip.cc54
-rw-r--r--gtk2_ardour/mixer_strip.h2
-rw-r--r--gtk2_ardour/mono_panner.cc609
-rw-r--r--gtk2_ardour/mono_panner.h11
-rw-r--r--gtk2_ardour/panner_ui.cc160
-rw-r--r--gtk2_ardour/panner_ui.h6
-rw-r--r--gtk2_ardour/processor_box.cc35
-rw-r--r--gtk2_ardour/processor_box.h2
-rw-r--r--gtk2_ardour/stereo_panner.cc150
-rw-r--r--gtk2_ardour/stereo_panner.h11
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__ */