コード例 #1
0
ファイル: viewer.c プロジェクト: BIANZiyang/3PRE
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;
}