1 /* 2 * Copyright (C) 2005-2014 Paul Davis <paul@linuxaudiosystems.com> 3 * Copyright (C) 2005 Taybin Rutkin <taybin@taybin.com> 4 * Copyright (C) 2009-2011 Carl Hetherington <carl@carlh.net> 5 * Copyright (C) 2009-2011 David Robillard <d@drobilla.net> 6 * Copyright (C) 2014-2015 Robin Gareus <robin@gareus.org> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License along 19 * with this program; if not, write to the Free Software Foundation, Inc., 20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 */ 22 23 #ifndef __ardour_panner_2d_h__ 24 #define __ardour_panner_2d_h__ 25 26 #include <sys/types.h> 27 #include <map> 28 #include <vector> 29 30 #include <glibmm/refptr.h> 31 #include <gtkmm/drawingarea.h> 32 #include <gtkmm/window.h> 33 #include <gtkmm/box.h> 34 #include <gtkmm/button.h> 35 #include <gtkmm/spinbutton.h> 36 #include <gtkmm/adjustment.h> 37 38 #include "pbd/cartesian.h" 39 40 #include "ardour_window.h" 41 42 namespace ARDOUR { 43 class PannerShell; 44 } 45 46 namespace Gtk { 47 class Menu; 48 class CheckMenuItem; 49 } 50 51 namespace Pango { 52 class Container; 53 } 54 55 class Panner2dWindow; 56 57 class Panner2d : public Gtk::DrawingArea 58 { 59 public: 60 Panner2d (boost::shared_ptr<ARDOUR::PannerShell>, int32_t height); 61 ~Panner2d (); 62 63 void allow_target_motion (bool); 64 65 int add_speaker (const PBD::AngularVector&); 66 int add_signal (const char* text, const PBD::AngularVector&); 67 void move_signal (int which, const PBD::AngularVector&); 68 void reset (uint32_t n_inputs); 69 void set_send_drawing_mode (bool); 70 get_panner_shell()71 boost::shared_ptr<ARDOUR::PannerShell> get_panner_shell() const { return panner_shell; } 72 73 void cart_to_gtk (PBD::CartesianVector&) const; 74 void gtk_to_cart (PBD::CartesianVector&) const; 75 76 protected: 77 bool on_expose_event (GdkEventExpose *); 78 bool on_button_press_event (GdkEventButton *); 79 bool on_button_release_event (GdkEventButton *); 80 bool on_motion_notify_event (GdkEventMotion *); 81 bool on_scroll_event (GdkEventScroll *); 82 void on_size_allocate (Gtk::Allocation& alloc); 83 84 private: 85 class Target { 86 public: 87 PBD::AngularVector position; 88 bool visible; 89 std::string text; 90 91 Target (const PBD::AngularVector&, const char* txt = 0); 92 ~Target (); 93 94 void set_text (const char*); set_selected(bool yn)95 void set_selected (bool yn) { 96 _selected = yn; 97 } selected()98 bool selected() const { 99 return _selected; 100 } 101 102 private: 103 bool _selected; 104 }; 105 106 struct ColorScheme { 107 uint32_t background; 108 uint32_t crosshairs; 109 uint32_t signalcircle_border; 110 uint32_t signalcircle; 111 uint32_t diffusion; 112 uint32_t diffusion_inv; 113 uint32_t pos_outline; 114 uint32_t pos_fill; 115 uint32_t signal_outline; 116 uint32_t signal_fill; 117 uint32_t speaker_fill; 118 uint32_t text; 119 uint32_t send_bg; 120 uint32_t send_pan; 121 }; 122 123 static ColorScheme colors; 124 static void set_colors (); 125 static bool have_colors; 126 void color_handler (); 127 128 boost::shared_ptr<ARDOUR::PannerShell> panner_shell; 129 Glib::RefPtr<Pango::Layout> layout; 130 131 typedef std::vector<Target*> Targets; 132 Targets speakers; 133 Targets signals; 134 Target position; 135 136 Target *drag_target; 137 int width; 138 int height; 139 double radius; 140 double border; 141 double hoffset; 142 double voffset; 143 double last_width; 144 bool did_move; 145 bool have_elevation; 146 bool _send_mode; 147 148 Target *find_closest_object (gdouble x, gdouble y, bool& is_signal); 149 150 gint handle_motion (gint, gint, GdkModifierType); 151 152 void toggle_bypass (); 153 void handle_state_change (); 154 void handle_position_change (); 155 void label_signals (); 156 157 PBD::ScopedConnectionList panshell_connections; 158 PBD::ScopedConnectionList panner_connections; 159 160 /* cartesian coordinates in GTK units ; adjust to same but on a circle of radius 1.0 161 and centered in the middle of our area 162 */ 163 void clamp_to_circle (double& x, double& y); 164 void sphere_project (double& x, double& y, double& z); 165 }; 166 167 class Panner2dWindow : public ArdourWindow 168 { 169 public: 170 Panner2dWindow (boost::shared_ptr<ARDOUR::PannerShell>, int32_t height, uint32_t inputs); 171 172 void reset (uint32_t n_inputs); 173 174 private: 175 Panner2d widget; 176 177 Gtk::HBox hpacker; 178 Gtk::VBox button_box; 179 Gtk::ToggleButton bypass_button; 180 Gtk::VBox spinner_box; 181 Gtk::VBox left_side; 182 183 Gtk::Adjustment width_adjustment; 184 Gtk::SpinButton width_spinner; 185 186 PBD::ScopedConnectionList panshell_connections; 187 PBD::ScopedConnectionList panvalue_connections; 188 void set_bypassed(); 189 void set_width(); 190 191 void pannable_handler (); 192 void bypass_toggled (); 193 void width_changed (); 194 bool on_key_press_event (GdkEventKey*); 195 bool on_key_release_event (GdkEventKey*); 196 }; 197 198 #endif /* __ardour_panner_2d_h__ */ 199