37 , aspect_frame (
"", 0.5, 0.5, 1.5, false)
38 , azimuth_adjustment (0, 0.0, 360.0, 10.0, 1.0)
39 , azimuth_spinner (azimuth_adjustment)
40 , add_speaker_button (
_(
"Add Speaker"))
41 , remove_speaker_button (
_(
"Remove Speaker"))
44 , ignore_speaker_position_change (false)
45 , ignore_azimuth_change (false)
57 hbox.set_border_width (6);
61 HBox* current_speaker_hbox = manage (
new HBox);
62 current_speaker_hbox->set_spacing (4);
63 current_speaker_hbox->pack_start (*manage (
new Label (
_(
"Azimuth:"))),
false,
false);
67 VBox* vbox = manage (
new VBox);
68 vbox->pack_start (
hbox);
69 vbox->pack_start (*current_speaker_hbox,
true,
true);
73 darea.add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::POINTER_MOTION_MASK);
116 cr = gdk_cairo_create (
darea.get_window()->gobj());
118 cairo_set_line_width (cr, 1.0);
120 cairo_rectangle (cr, event->area.x, event->area.y, event->area.width, event->area.height);
121 cairo_set_source_rgba (cr, 0.1, 0.1, 0.1, 1.0);
122 cairo_fill_preserve (cr);
129 cairo_set_source_rgb (cr, 0.0, 0.1, 0.7);
130 cairo_move_to (cr, 0.5,
height/2.0+0.5);
136 cairo_move_to (cr,
width/2+0.5, 0.5);
147 cairo_select_font_face (cr,
"sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
150 cairo_set_font_size (cr, 10);
153 cairo_set_font_size (cr, 16);
158 for (vector<Speaker>::iterator i = speakers->
speakers().begin(); i != speakers->
speakers().end(); ++i) {
171 x = (gint) floor (c.x);
172 y = (gint) floor (c.y);
176 cairo_arc (cr, x, y, arc_radius, 0, 2.0 * M_PI);
178 cairo_set_source_rgb (cr, 0.8, 0.8, 0.2);
180 cairo_set_source_rgb (cr, 0.8, 0.2, 0.1);
182 cairo_close_path (cr);
185 cairo_move_to (cr, x + 6, y + 6);
189 snprintf (buf,
sizeof (buf),
"%d:%d", n+1, (
int) lrint (s.
angles().
azi));
191 snprintf (buf,
sizeof (buf),
"%d", n + 1);
193 cairo_show_text (cr, buf);
249 width = alloc.get_width();
250 height = alloc.get_height();
276 GdkModifierType state;
278 if (ev->type == GDK_2BUTTON_PRESS && ev->button == 1) {
284 switch (ev->button) {
292 int const drag_x = (int) floor (ev->x);
293 int const drag_y = (int) floor (ev->y);
294 state = (GdkModifierType) ev->state;
324 GdkModifierType state;
327 switch (ev->button) {
329 x = (int) floor (ev->x);
330 y = (int) floor (ev->y);
331 state = (GdkModifierType) ev->state;
333 if (Keyboard::modifier_state_contains (state, Keyboard::TertiaryModifier)) {
335 for (vector<Speaker>::iterator i = speakers->
speakers().begin(); i != speakers->
speakers().end(); ++i) {
349 x = (int) floor (ev->x);
350 y = (int) floor (ev->y);
351 state = (GdkModifierType) ev->state;
375 float best_distance = FLT_MAX;
379 for (vector<Speaker>::iterator i = speakers->
speakers().begin(); i != speakers->
speakers().end(); ++i, ++n) {
387 distance = sqrt ((c.
x - x) * (c.
x - x) +
388 (c.
y - y) * (c.
y - y));
391 if (distance < best_distance) {
392 best_distance = distance;
397 if (best_distance > 20) {
408 GdkModifierType state;
411 gdk_window_get_pointer (ev->window, &x, &y, &state);
413 x = (int) floor (ev->x);
414 y = (int) floor (ev->y);
415 state = (GdkModifierType) ev->state;
433 if ((state & (GDK_BUTTON1_MASK|GDK_BUTTON2_MASK)) == 0) {
449 if (state & GDK_BUTTON1_MASK && !(state & GDK_BUTTON2_MASK)) {
451 bool need_move =
false;
457 if (obx != c.
x || oby != c.
y) {
int height
height of the circle
int y_origin
y origin of our stuff within the drawing area
void set_speakers(boost::shared_ptr< ARDOUR::Speakers >)
Gtk::AspectFrame aspect_frame
void darea_size_allocate(Gtk::Allocation &alloc)
bool darea_motion_notify_event(GdkEventMotion *ev)
void cartesian(CartesianVector &c) const
bool darea_button_release_event(GdkEventButton *ev)
void speaker_position_changed()
bool darea_button_press_event(GdkEventButton *ev)
virtual void remove_speaker(int id)
bool ignore_azimuth_change
Gtk::Adjustment azimuth_adjustment
const PBD::CartesianVector & coords() const
void angular(AngularVector &a) const
void gtk_to_cart(PBD::CartesianVector &c) const
int find_closest_object(gdouble x, gdouble y)
virtual int add_speaker(const PBD::AngularVector &)
Gtk::Button add_speaker_button
int width
width of the circle
boost::shared_ptr< ARDOUR::Speakers > get_speakers() const
std::vector< Speaker > & speakers()
boost::weak_ptr< ARDOUR::Speakers > _speakers
LIBPBD_API void cartesian_to_spherical(double x, double y, double z, double &azi, double &ele, double &len)
bool darea_expose_event(GdkEventExpose *)
Gtk::SpinButton azimuth_spinner
int x_origin
x origin of our stuff within the drawing area
Gtk::Button remove_speaker_button
void cart_to_gtk(PBD::CartesianVector &c) const
virtual void move_speaker(int id, const PBD::AngularVector &new_position)
LIBPBD_API void spherical_to_cartesian(double azi, double ele, double len, double &x, double &y, double &z)
int selected_index
index of any selected speaker, or -1
#define MISSING_INVALIDATOR
bool ignore_speaker_position_change
PBD::ScopedConnection selected_speaker_connection
const PBD::AngularVector & angles() const
void clamp_to_circle(double &x, double &y)
bool handle_motion(gint evx, gint evy, GdkModifierType state)