25 #include <gtkmm/menu.h>
36 #include "canvas/colors.h"
89 set_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::POINTER_MOTION_MASK);
109 while (
signals.size() < n_inputs) {
113 if (
signals.size() > n_inputs) {
114 for (uint32_t i =
signals.size(); i < n_inputs; ++i) {
123 for (uint32_t i = 0; i < n_inputs; ++i) {
134 for (uint32_t i = nouts; i <
speakers.size(); ++i) {
142 (*x)->visible =
false;
147 for (uint32_t n = 0; n < nouts; ++n) {
150 snprintf (buf,
sizeof (buf),
"%d", n+1);
152 speakers[n]->position = the_speakers[n].angles();
162 width = alloc.get_width();
163 height = alloc.get_height();
182 DrawingArea::on_size_allocate (alloc);
245 for (uint32_t i = 0; i < sz; ++i) {
247 snprintf (buf,
sizeof (buf),
"%" PRIu32, i + 1);
263 for (uint32_t i = 0; i <
signals.size(); ++i) {
276 for (n = 0; n <
speakers.size(); ++n) {
277 speakers[n]->position = the_speakers[n].angles();
286 if (which >=
int (
speakers.size())) {
300 float best_distance = FLT_MAX;
311 best_distance = sqrt ((c.
x - x) * (c.
x - x) +
312 (c.
y - y) * (c.
y - y));
315 #if 0 // TODO signal grab -> change width, not position
316 for (Targets::const_iterator i =
signals.begin(); i !=
signals.end(); ++i) {
322 distance = sqrt ((c.
x - x) * (c.
x - x) +
323 (c.
y - y) * (c.
y - y));
325 if (distance < best_distance) {
327 best_distance = distance;
336 if (best_distance > 30) {
341 if (best_distance > 10) {
349 for (Targets::const_iterator i =
speakers.begin(); i !=
speakers.end(); ++i) {
357 distance = sqrt ((c.
x - x) * (c.
x - x) +
358 (c.
y - y) * (c.
y - y));
360 if (distance < best_distance) {
362 best_distance = distance;
368 if (best_distance < 30) {
375 if (best_distance < 10) {
399 GdkModifierType state;
402 gdk_window_get_pointer (ev->window, &x, &y, &state);
404 x = (int) floor (ev->x);
405 y = (int) floor (ev->y);
406 state = (GdkModifierType) ev->state;
409 if (ev->state & (GDK_BUTTON1_MASK|GDK_BUTTON2_MASK)) {
422 const double diameter =
radius*2.0;
424 cr = gdk_cairo_create (get_window()->gobj());
428 cairo_rectangle (cr, event->area.x, event->area.y, event->area.width, event->area.height);
435 cairo_set_source_rgba (cr, r, g, b, 1.0);
437 cairo_set_source_rgba (cr, r, g, b , 0.2);
439 cairo_fill_preserve (cr);
446 cairo_set_line_width (cr, 1.0);
450 cairo_set_source_rgba (cr, 0.282, 0.517, 0.662, 1.0);
451 cairo_move_to (cr, 0.0,
radius);
452 cairo_line_to (cr, diameter,
radius);
457 cairo_move_to (cr,
radius, 0);
458 cairo_line_to (cr,
radius, diameter);
463 cairo_set_line_width (cr, 1.5);
464 cairo_set_source_rgba (cr, 0.517, 0.772, 0.882, 1.0);
468 for (uint32_t rad = 15; rad < 90; rad += 15) {
469 cairo_set_line_width (cr, .5 + (
float)rad / 150.0);
471 cairo_set_source_rgba (cr, 0.282, 0.517, 0.662, 1.0);
473 cairo_set_source_rgba (cr, 0.282, 0.517, 0.662, 0.8);
476 cairo_arc (cr,
radius,
radius,
radius * sin(M_PI * (
float) rad / 180.0), 0, 2.0 * M_PI);
486 double width_angle = fabs (
panner_shell->
pannable()->pan_width_control->get_value()) * 2 * M_PI;
491 cairo_rotate (cr, M_PI / 2.0);
492 cairo_rotate (cr, position_angle - (width_angle/2.0));
493 cairo_move_to (cr, 0, 0);
494 cairo_arc_negative (cr, 0, 0,
radius, width_angle, 0.0);
495 cairo_close_path (cr);
498 cairo_set_source_rgba (cr, 0.282, 0.517, 0.662, 0.45);
501 cairo_set_source_rgba (cr, 1.0, 0.419, 0.419, 0.45);
509 cairo_select_font_face (cr,
"sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
514 cairo_set_font_size (cr, 10);
527 cairo_arc (cr, c.
x, c.
y, arc_radius + 1.0, 0, 2.0 * M_PI);
528 cairo_set_source_rgba (cr, 1.0, 0.419, 0.419, 0.85);
529 cairo_fill_preserve (cr);
530 cairo_set_source_rgba (cr, 1.0, 0.905, 0.905, 0.85);
536 for (Targets::iterator i =
signals.begin(); i !=
signals.end(); ++i) {
551 cairo_arc (cr, c.
x, c.
y, arc_radius, 0, 2.0 * M_PI);
552 cairo_set_source_rgba (cr, 0.282, 0.517, 0.662, 0.75);
553 cairo_fill_preserve (cr);
554 cairo_set_source_rgba (cr, 0.517, 0.772, 0.882, 0.8);
557 if (!xsmall && !signal->
text.empty()) {
558 cairo_set_source_rgba (cr, 0.517, 0.772, 0.882, .9);
563 cairo_move_to (cr, c.
x - 1, c.
y + 1);
565 cairo_move_to (cr, c.
x - 4, c.
y + 4);
567 cairo_show_text (cr, signal->
text.c_str());
590 snprintf (buf,
sizeof (buf),
"%d", n);
594 cairo_move_to (cr, c.
x, c.
y);
596 cairo_rotate (cr, -(sp.
azi/360.0) * (2.0 * M_PI));
598 cairo_scale (cr, 0.8, 0.8);
600 cairo_scale (cr, 1.2, 1.2);
602 cairo_rel_line_to (cr, 4, -2);
603 cairo_rel_line_to (cr, 0, -7);
604 cairo_rel_line_to (cr, 5, +5);
605 cairo_rel_line_to (cr, 5, 0);
606 cairo_rel_line_to (cr, 0, 5);
607 cairo_rel_line_to (cr, -5, 0);
608 cairo_rel_line_to (cr, -5, +5);
609 cairo_rel_line_to (cr, 0, -7);
610 cairo_close_path (cr);
611 cairo_set_source_rgba (cr, 0.282, 0.517, 0.662, 1.0);
616 cairo_set_font_size (cr, 16);
624 cairo_move_to (cr, c.
x, c.
y);
625 cairo_show_text (cr, buf);
640 GdkModifierType state;
645 if (ev->type == GDK_2BUTTON_PRESS && ev->button == 1) {
651 switch (ev->button) {
666 state = (GdkModifierType) ev->state;
681 GdkModifierType state;
684 switch (ev->button) {
686 x = (int) floor (ev->x);
687 y = (int) floor (ev->y);
688 state = (GdkModifierType) ev->state;
694 x = (int) floor (ev->x);
695 y = (int) floor (ev->y);
696 state = (GdkModifierType) ev->state;
698 if (Keyboard::modifier_state_contains (state, Keyboard::TertiaryModifier)) {
723 if ((state & (GDK_BUTTON1_MASK|GDK_BUTTON2_MASK)) == 0) {
730 if (state & GDK_BUTTON1_MASK && !(state & GDK_BUTTON2_MASK)) {
732 bool need_move =
false;
737 if ((evx != c.
x) || (evy != c.
y)) {
749 av.
azi = fmod(270 - av.
azi, 360);
751 double degree_fract = av.
azi / 360.0;
758 double r2d = 180.0 / M_PI;
759 av.
azi = r2d * atan2(cp.
y, cp.
x);
760 av.
ele = r2d * asin(cp.
z);
761 av.
azi = fmod(270 - av.
azi, 360);
764 double azi_fract = av.
azi / 360.0;
765 double ele_fract = av.
ele / 90.0;
779 switch (ev->direction) {
781 case GDK_SCROLL_RIGHT:
785 case GDK_SCROLL_DOWN:
786 case GDK_SCROLL_LEFT:
807 const double diameter =
radius*2.0;
809 c.
x = diameter * ((c.
x + 1.0) / 2.0);
811 c.
y = diameter - (diameter * ((c.
y + 1.0) / 2.0));
817 const double diameter =
radius*2.0;
818 c.
x = ((c.
x / diameter) * 2.0) - 1.0;
819 c.
y = (((diameter - c.
y) / diameter) * 2.0) - 1.0;
856 , bypass_button (
_(
"Bypass"))
857 , width_adjustment (0, -100, 100, 1, 5, 0)
858 , width_spinner (width_adjustment)
860 widget.set_name (
"MixerPanZone");
862 set_title (
_(
"Panner"));
863 widget.set_size_request (h, h);
881 Gtk::Label* l = manage (
new Label (
883 Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER,
false));
953 if (p == params.end()) {
bool relay_key_press(GdkEventKey *ev, Gtk::Window *win)
bool on_key_press_event(GdkEventKey *)
bool on_button_release_event(GdkEventButton *)
PBD::ScopedConnectionList panshell_connections
void handle_state_change()
void set_selected(bool yn)
Gtk::SpinButton width_spinner
PBD::Signal0< void > PannableChanged
void reset(uint32_t n_inputs)
void sphere_project(double &x, double &y, double &z)
PBD::ScopedConnectionList panvalue_connections
void reset(uint32_t n_inputs)
void cartesian(CartesianVector &c) const
static const int large_size_threshold
Target * find_closest_object(gdouble x, gdouble y, bool &is_signal)
Panner2d(boost::shared_ptr< ARDOUR::PannerShell >, int32_t height)
static const int small_border_width
PBD::ScopedConnectionList panshell_connections
PBD::AngularVector position
static const int large_border_width
int add_signal(const char *text, const PBD::AngularVector &)
LIBGTKMM2EXT_API uint64_t Keyboard
void angular(AngularVector &a) const
void set_text(const char *)
boost::shared_ptr< ARDOUR::PannerShell > get_panner_shell() const
void cart_to_gtk(PBD::CartesianVector &) const
Target(const PBD::AngularVector &, const char *txt=0)
Panner2dWindow(boost::shared_ptr< ARDOUR::PannerShell >, int32_t height, uint32_t inputs)
void handle_position_change()
int add_speaker(const PBD::AngularVector &)
gint handle_motion(gint, gint, GdkModifierType)
LIBPBD_API void cartesian_to_spherical(double x, double y, double z, double &azi, double &ele, double &len)
boost::shared_ptr< ARDOUR::PannerShell > panner_shell
bool on_button_press_event(GdkEventButton *)
static PublicEditor & instance()
bool on_expose_event(GdkEventExpose *)
void set_send_drawing_mode(bool)
Gtk::ToggleButton bypass_button
void gtk_to_cart(PBD::CartesianVector &) const
PBD::Signal0< void > Changed
bool on_motion_notify_event(GdkEventMotion *)
void on_size_allocate(Gtk::Allocation &alloc)
LIBARDOUR_API PBD::PropertyDescriptor< framepos_t > position
static UIConfiguration * config()
bool on_key_release_event(GdkEventKey *)
LIBPBD_API void spherical_to_cartesian(double azi, double ele, double len, double &x, double &y, double &z)
boost::shared_ptr< Pannable > pannable() const
void move_signal(int which, const PBD::AngularVector &)
PBD::ScopedConnectionList panner_connections
boost::shared_ptr< Panner > panner() const
bool on_scroll_event(GdkEventScroll *)
void clamp_to_circle(double &x, double &y)
LIBARDOUR_API PBD::PropertyDescriptor< bool > color