static gboolean on_button_press (GtkWidget *widget, GdkEventButton *event, void *user_data) { Viewer *self = (Viewer*) user_data; gtku_gl_drawing_area_set_context (self->gl_area); double ray_start[3]; double ray_dir[3]; _window_coord_to_ray (event->x, widget->allocation.height - event->y, ray_start, ray_dir); // find a new picker? double best_distance = HUGE; EventHandler *best_handler = NULL; if (self->picking_handler == NULL || self->picking_handler->picking==0) { for (unsigned int eidx = 0; eidx < g_ptr_array_size(self->event_handlers); eidx++) { EventHandler *handler = g_ptr_array_index(self->event_handlers, eidx); if (handler->enabled && handler->pick_query) { double this_distance = handler->pick_query(self, handler, ray_start, ray_dir); if (this_distance < best_distance && this_distance >= 0) { best_distance = this_distance; best_handler = handler; } } } // notify the new handler if (best_handler) viewer_request_pick(self, best_handler); } // give picking handler first dibs int consumed = 0; if (self->picking_handler && !self->picking_handler->picking) self->picking_handler = NULL; if (self->picking_handler && self->picking_handler->enabled && self->picking_handler->mouse_press) { consumed = self->picking_handler->mouse_press(self, self->picking_handler, ray_start, ray_dir, event); update_status_bar(self); } // try all the other handlers in order of priority for (unsigned int eidx = 0; !consumed && eidx < g_ptr_array_size(self->event_handlers); eidx++) { EventHandler *handler = g_ptr_array_index(self->event_handlers, eidx); if (handler != self->picking_handler && handler->enabled && handler->mouse_press) if (handler->mouse_press(self, handler, ray_start, ray_dir, event)) break; } return TRUE; }