static gboolean on_button_press (GooCanvasItem *item, GooCanvasItem *target, GdkEventButton *event, gpointer data) { GooCanvasItemModel *model = goo_canvas_item_get_model (target); char *item_id = g_object_get_data (G_OBJECT (model), "id"); g_print ("%s received 'button-press' signal\n", item_id); if (strstr (item_id, "explicit")) { GooCanvas *canvas; GdkGrabStatus status; GdkEventMask mask = GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK; canvas = goo_canvas_item_get_canvas (item); status = goo_canvas_pointer_grab (canvas, item, mask, NULL, event->time); if (status == GDK_GRAB_SUCCESS) g_print ("grabbed pointer\n"); else g_print ("pointer grab failed\n"); } return FALSE; }
static gboolean on_button_press_event_cb (GooCanvasItem *item, GooCanvasItem *target_item, GdkEventButton *event, gpointer user_data) { GooCanvasItemModel *model = goo_canvas_item_get_model (item); if (event->state & GDK_CONTROL_MASK) { if (event->button == 1 || event->button == 3) { if (event->button == 1) drag_mode = MODE_MOVE; else drag_mode = MODE_RESIZE; drag_item = item; drag_x = event->x; drag_y = event->y; g_object_get (G_OBJECT (model), "x", &item_x, "y", &item_y, "width", &item_width, "height", &item_height, NULL); goo_canvas_pointer_grab (GOO_CANVAS (user_data), item, GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_RELEASE_MASK, NULL, event->time); return TRUE; } } return FALSE; }
static VALUE rg_pointer_grab(VALUE self, VALUE item, VALUE event_mask, VALUE cursor, VALUE etime) { return GENUM2RVAL( goo_canvas_pointer_grab(SELF(self), RVAL2GOOCANVASITEM(item), NUM2INT(event_mask), (GdkCursor *)RVAL2BOXED(cursor, GDK_TYPE_CURSOR), NIL_P(etime) ? 0 : NUM2UINT(etime)), GDK_TYPE_GRAB_STATUS); }
gboolean sheet_pointer_grab (Sheet *sheet, GdkEvent *event) { g_return_val_if_fail (sheet, FALSE); g_return_val_if_fail (IS_SHEET (sheet), FALSE); #ifndef DEBUG_DISABLE_GRABBING if (sheet->priv->pointer_grabbed == 0 && goo_canvas_pointer_grab (GOO_CANVAS (sheet), GOO_CANVAS_ITEM (sheet->grid), GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK, NULL, extract_time (event)) == GDK_GRAB_SUCCESS) { sheet->priv->pointer_grabbed = 1; } return (sheet->priv->pointer_grabbed == 1); #else return TRUE; #endif }
static gboolean on_button_press (GooCanvasItem *item, GooCanvasItem *target, GdkEventButton *event, gpointer data) { GooCanvas *canvas; GdkCursor *fleur; fleur = gdk_cursor_new (GDK_FLEUR); canvas = goo_canvas_item_get_canvas (item); goo_canvas_pointer_grab (canvas, item, GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_RELEASE_MASK, fleur, event->time); g_object_unref (fleur); return TRUE; }
void sheet_setup_rubberband (Sheet *sheet, GdkEventButton *event) { double x, y; cairo_pattern_t *pattern; static guchar stipple_data[16] = {0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255 }; x = event->x; //the x coordinate of the pointer relative to the window. y = event->y; //the y coordinate of the pointer relative to the window. goo_canvas_convert_from_pixels (GOO_CANVAS (sheet), &x, &y); sheet->priv->rubberband->start_x = x; sheet->priv->rubberband->start_y = y; sheet->priv->rubberband->state = RUBBER_YES; sheet->priv->rubberband->click_start_state = event->state; pattern = create_stipple ("lightgrey", stipple_data); sheet->priv->rubberband->rectangle = goo_canvas_rect_new ( GOO_CANVAS_ITEM (sheet->object_group), x, y, 0.0, 0.0, "stroke-color", "black", "line-width", 0.2, "fill-pattern", pattern, NULL); goo_canvas_pointer_grab (GOO_CANVAS (sheet), GOO_CANVAS_ITEM (sheet->grid), (GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK), NULL, event->time); // Mark all the selected objects to preserve their selected state // if SHIFT is pressed while rubberbanding. if (event->state & GDK_SHIFT_MASK) { sheet->priv->preserve_selection_items = g_list_copy (sheet_preserve_selection (sheet)); } }
// Event handler for a SheetItem gboolean sheet_item_event (GooCanvasItem *sheet_item, GooCanvasItem *sheet_target_item, GdkEvent *event, Sheet *sheet) { // Remember the last position of the mouse cursor. static double last_x, last_y; GooCanvas *canvas; SheetPriv *priv; GList *list; // Mouse cursor position in window coordinates, snapped to the grid spacing. double snapped_x, snapped_y; // Move the selected item(s) by this movement. double dx, dy; g_return_val_if_fail (sheet_item != NULL, FALSE); g_return_val_if_fail (sheet != NULL, FALSE); priv = sheet->priv; canvas = GOO_CANVAS (sheet); switch (event->type) { case GDK_BUTTON_PRESS: // Grab focus to sheet for correct use of events gtk_widget_grab_focus (GTK_WIDGET (sheet)); switch (event->button.button) { case 1: g_signal_stop_emission_by_name (sheet_item, "button_press_event"); sheet->state = SHEET_STATE_DRAG_START; sheet_get_pointer (sheet, &last_x, &last_y); break; case 3: g_signal_stop_emission_by_name (sheet_item, "button_press_event"); if (sheet->state != SHEET_STATE_NONE) return TRUE; // Bring up a context menu for right button clicks. if (!SHEET_ITEM (sheet_item)->priv->selected && !((event->button.state & GDK_SHIFT_MASK) == GDK_SHIFT_MASK)) sheet_select_all (sheet, FALSE); sheet_item_select (SHEET_ITEM (sheet_item), TRUE); sheet_item_run_menu (SHEET_ITEM (sheet_item), sheet, (GdkEventButton *) event); break; default: return FALSE; } break; case GDK_2BUTTON_PRESS: // Do not interfere with object dragging. if (sheet->state == SHEET_STATE_DRAG) return FALSE; switch (event->button.button) { case 1: if (sheet->state == SHEET_STATE_DRAG_START) sheet->state = SHEET_STATE_NONE; g_signal_stop_emission_by_name (sheet_item, "button_press_event"); g_signal_emit_by_name (sheet_item, "double_clicked"); break; default: return FALSE; } break; case GDK_3BUTTON_PRESS: g_signal_stop_emission_by_name (sheet_item, "button_press_event"); return TRUE; case GDK_BUTTON_RELEASE: switch (event->button.button) { case 1: if (sheet->state != SHEET_STATE_DRAG && sheet->state != SHEET_STATE_DRAG_START) return TRUE; g_signal_stop_emission_by_name (sheet_item, "button-release-event"); if (sheet->state == SHEET_STATE_DRAG_START) { sheet->state = SHEET_STATE_NONE; if (!(event->button.state & GDK_SHIFT_MASK)) sheet_select_all (sheet, FALSE); if (IS_SHEET_ITEM (sheet_item)) sheet_item_select (SHEET_ITEM (sheet_item), TRUE); return TRUE; } // Get the mouse motion sheet_get_pointer (sheet, &snapped_x, &snapped_y); snapped_x -= last_x; snapped_y -= last_y; sheet->state = SHEET_STATE_NONE; goo_canvas_pointer_ungrab (canvas, GOO_CANVAS_ITEM (sheet_item), event->button.time); // Reparent the selected objects to the normal group // to have correct behaviour for (list = priv->selected_objects; list; list = list->next) { sheet_item_reparent (SHEET_ITEM (list->data), sheet->object_group); } for (list = priv->selected_objects; list; list = list->next) { ItemData *item_data; Coords pos; item_data = SHEET_ITEM (list->data)->priv->data; pos.x = snapped_x; pos.y = snapped_y; item_data_move (item_data, &pos); item_data_register (item_data); } g_list_free_full (list, g_object_unref); break; } case GDK_KEY_PRESS: switch (event->key.keyval) { case GDK_KEY_r: sheet_rotate_selection (sheet); { gdouble x, y; GooCanvasBounds bounds; sheet_get_pointer (sheet, &x, &y); // Center the objects around the mouse pointer. goo_canvas_item_get_bounds ( GOO_CANVAS_ITEM (priv->floating_group), &bounds); dx = x - (bounds.x1 + bounds.x2) / 2; dy = y - (bounds.y1 + bounds.y2) / 2; snap_to_grid (sheet->grid, &dx, &dy); goo_canvas_item_translate ( GOO_CANVAS_ITEM (priv->floating_group), dx, dy); last_x = snapped_x; last_y = snapped_y; } break; default: return FALSE; } return TRUE; case GDK_MOTION_NOTIFY: if (sheet->state != SHEET_STATE_DRAG && sheet->state != SHEET_STATE_DRAG_START) return FALSE; if (sheet->state == SHEET_STATE_DRAG_START) { sheet->state = SHEET_STATE_DRAG; // Update the selection if needed. if (IS_SHEET_ITEM (sheet_item) && (!SHEET_ITEM (sheet_item)->priv->selected)) { if (!(event->button.state & GDK_SHIFT_MASK)) { sheet_select_all (sheet, FALSE); } sheet_item_select (SHEET_ITEM (sheet_item), TRUE); } // Reparent the selected objects so that we can move them // efficiently. for (list = priv->selected_objects; list; list = list->next) { ItemData *item_data; item_data = SHEET_ITEM (list->data)->priv->data; item_data_unregister (item_data); sheet_item_reparent (SHEET_ITEM (list->data), priv->selected_group); } goo_canvas_pointer_grab (canvas, GOO_CANVAS_ITEM (sheet_item), GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK, NULL, event->button.time); } // Set last_x & last_y to the pointer position sheet_get_pointer (sheet, &snapped_x, &snapped_y); dx = snapped_x - last_x; dy = snapped_y - last_y; // Check that we don't move outside the sheet... // Horizontally: /* if (cx1 <= 0) { // leftmost edge dx = dx - x1; snap_to_grid (sheet->grid, &dx, NULL); snapped_x = last_x + dx; } else if (cx2 >= sheet_width) { // rightmost edge dx = dx - (x2 - sheet_width / priv->zoom); snap_to_grid (sheet->grid, &dx, NULL); snapped_x = last_x + dx; } // And vertically: if (cy1 <= 0) { // upper edge dy = dy - y1; snap_to_grid (sheet->grid, NULL, &dy); snapped_y = last_y + dy; } else if (cy2 >= sheet_height) { // lower edge dy = dy - (y2 - sheet_height / priv->zoom); snap_to_grid (sheet->grid, NULL, &dy); snapped_y = last_y + dy; } //last_x = snapped_x; //last_y = snapped_y; */ goo_canvas_item_set_transform (GOO_CANVAS_ITEM (priv->selected_group), NULL); goo_canvas_item_translate (GOO_CANVAS_ITEM (priv->selected_group), dx, dy); return TRUE; default: return FALSE; } return TRUE; }