Exemplo n.º 1
0
void sheet_item_select_in_area (SheetItem *item, Coords *p1, Coords *p2)
{
	SheetItemClass *sheet_item_class;
	gboolean in_area;

	g_return_if_fail (item != NULL);
	g_return_if_fail (IS_SHEET_ITEM (item));
	g_return_if_fail (p1 != NULL);
	g_return_if_fail (p2 != NULL);

	sheet_item_class = SHEET_ITEM_CLASS (G_OBJECT_GET_CLASS (item));
	in_area = sheet_item_class->is_in_area (item, p1, p2);

	if (in_area && !item->priv->selected)
		sheet_item_select (item, TRUE);
	else if (!in_area && item->priv->selected && !item->priv->preserve_selection)
		sheet_item_select (item, FALSE);
}
Exemplo n.º 2
0
/**
 * select all items on the sheet
 */
void sheet_select_all (Sheet *sheet, gboolean select)
{
	GList *list;

	g_return_if_fail (sheet != NULL);
	g_return_if_fail (IS_SHEET (sheet));

	for (list = sheet->priv->items; list; list = list->next)
		sheet_item_select (SHEET_ITEM (list->data), select);

	if (!select)
		sheet_release_selected_objects (sheet);
}
Exemplo n.º 3
0
// 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;
}