Пример #1
0
static SPItem *
sp_quick_align_find_master (const GSList *slist, gboolean horizontal)
{
	NRRectF b;
	const GSList * l;
	SPItem * master, * item;
	gdouble dim, max;

	master = NULL;

	switch (base) {
	case SP_ALIGN_LAST:
		return (SPItem *) slist->data;
		break;
	case SP_ALIGN_FIRST: 
		return (SPItem *) g_slist_last ((GSList *) slist)->data;
		break;
	case SP_ALIGN_BIGGEST:
		max = -1e18;
		for (l = slist; l != NULL; l = l->next) {
			item = (SPItem *) l->data;
			sp_item_bbox_desktop (item, &b);
			if (horizontal) {
				dim = b.x1 - b.x0; 
			} else {
				dim = b.y1 - b.y0;
			}
			if (dim > max) {
				max = dim;
				master = item;
			}
		}
		return master;
		break;
	case SP_ALIGN_SMALLEST:
		max = 1e18;
		for (l = slist; l != NULL; l = l->next) {
			item = (SPItem *) l->data;
			sp_item_bbox_desktop (item, &b);
			if (horizontal) {
				dim = b.x1 - b.x0;
			} else {
				dim = b.y1 - b.y0;
			}
			if (dim < max) {
				max = dim;
				master = item;
			}
		}
		return master;
		break;
	default:
		g_assert_not_reached ();
		break;
	}

	return NULL;
}
static GSList *find_items_in_area(GSList *s, SPGroup *group, unsigned int dkey, Geom::Rect const &area,
                                  bool (*test)(Geom::Rect const &, Geom::Rect const &), bool take_insensitive = false)
{
    g_return_val_if_fail(SP_IS_GROUP(group), s);

    for (SPObject *o = sp_object_first_child(SP_OBJECT(group)) ; o != NULL ; o = SP_OBJECT_NEXT(o) ) {
        if (!SP_IS_ITEM(o)) {
            continue;
        }
        if (SP_IS_GROUP(o) && SP_GROUP(o)->effectiveLayerMode(dkey) == SPGroup::LAYER ) {
            s = find_items_in_area(s, SP_GROUP(o), dkey, area, test);
        } else {
            SPItem *child = SP_ITEM(o);
            Geom::OptRect box = sp_item_bbox_desktop(child);
            if ( box && test(area, *box) && (take_insensitive || child->isVisibleAndUnlocked(dkey))) {
                s = g_slist_append(s, child);
            }
        }
    }

    return s;
}
Пример #3
0
void
sp_align_distribute_v_clicked (GtkWidget *widget, const gchar *layout)
{
	SPDesktop *desktop;
	SPSelection *selection;
	const GSList *slist, *l;
	struct _SPBBoxSort *bbs;
	int len, pos;
	unsigned int changed;

	desktop = SP_ACTIVE_DESKTOP;
	if (!desktop) return;

	selection = SP_DT_SELECTION (desktop);
	slist = sp_selection_item_list (selection);
	if (!slist) return;
	if (!slist->next) return;

	len = g_slist_length ((GSList *) slist);
	bbs = g_new (struct _SPBBoxSort, len);
	pos = 0;
	for (l = slist; l != NULL; l = l->next) {
		bbs[pos].item = SP_ITEM (l->data);
		sp_item_bbox_desktop (bbs[pos].item, &bbs[pos].bbox);
		bbs[pos].anchor = 0.5 * layout[0] * bbs[pos].bbox.y0 + 0.5 * layout[1] * bbs[pos].bbox.y1;
		pos += 1;
	}

	qsort (bbs, len, sizeof (struct _SPBBoxSort), sp_align_bbox_sort);

	changed = FALSE;

	if (!layout[2]) {
		float dist, step;
		int i;
		dist = bbs[len - 1].anchor - bbs[0].anchor;
		step = dist / (len - 1);
		for (i = 0; i < len; i++) {
			float pos;
			pos = bbs[0].anchor + i * step;
			if (!NR_DF_TEST_CLOSE (pos, bbs[i].anchor, 1e-6)) {
				sp_item_move_rel (bbs[i].item, 0.0, pos - bbs[i].anchor);
				changed = TRUE;
			}
		}
	} else {
		/* Damn I am not sure, how to order them initially (Lauris) */
		float dist, span, step, pos;
		int i;
		dist = bbs[len - 1].bbox.y1 - bbs[0].bbox.y0;
		span = 0;
		for (i = 0; i < len; i++) span += (bbs[i].bbox.y1 - bbs[i].bbox.y0);
		step = (dist - span) / (len - 1);
		pos = bbs[0].bbox.y0;
		for (i = 0; i < len; i++) {
			if (!NR_DF_TEST_CLOSE (pos, bbs[i].bbox.y0, 1e-6)) {
				sp_item_move_rel (bbs[i].item, 0.0, pos - bbs[i].bbox.y0);
				changed = TRUE;
			}
			pos += (bbs[i].bbox.y1 - bbs[i].bbox.y0);
			pos += step;
		}
	}

	g_free (bbs);

	if (changed) {
		sp_selection_changed (selection);
		sp_document_done (SP_DT_DOCUMENT (desktop));
	}
}
Пример #4
0
void
sp_align_arrange_clicked (GtkWidget *widget, const gchar *aligns)
{
	float mx0, mx1, my0, my1;
	float sx0, sx1, sy0, sy1;
	SPDesktop * desktop;
	SPSelection * selection;
	GSList * slist;
	SPItem * master, * item;
	NRRectF b;
	NRPointF mp, sp;
	GSList * l;
	gboolean changed;

	mx0 = 0.5 * aligns[0];
	mx1 = 0.5 * aligns[1];
	my0 = 0.5 * aligns[2];
	my1 = 0.5 * aligns[3];
	sx0 = 0.5 * aligns[4];
	sx1 = 0.5 * aligns[5];
	sy0 = 0.5 * aligns[6];
	sy1 = 0.5 * aligns[7];

	desktop = SP_ACTIVE_DESKTOP;
	if (!desktop) return;

	selection = SP_DT_SELECTION (desktop);
	slist = (GSList *) sp_selection_item_list (selection);
	if (!slist) return;

	switch (base) {
	case SP_ALIGN_LAST:
	case SP_ALIGN_FIRST:
	case SP_ALIGN_BIGGEST:
	case SP_ALIGN_SMALLEST:
		if (!slist->next) return;
		slist = g_slist_copy (slist);
		master = sp_quick_align_find_master (slist, (mx0 != 0.0) || (mx1 != 0.0));
		slist = g_slist_remove (slist, master);
		sp_item_bbox_desktop (master, &b);
		mp.x = mx0 * b.x0 + mx1 * b.x1;
		mp.y = my0 * b.y0 + my1 * b.y1;
		break;
	case SP_ALIGN_PAGE:
		slist = g_slist_copy (slist);
		mp.x = mx1 * sp_document_width (SP_DT_DOCUMENT (desktop));
		mp.y = my1 * sp_document_height (SP_DT_DOCUMENT (desktop));
		break;
	case SP_ALIGN_DRAWING:
		slist = g_slist_copy (slist);
		sp_item_bbox_desktop ((SPItem *) sp_document_root (SP_DT_DOCUMENT (desktop)), &b);
		mp.x = mx0 * b.x0 + mx1 * b.x1;
		mp.y = my0 * b.y0 + my1 * b.y1;
		break;
	case SP_ALIGN_SELECTION:
		slist = g_slist_copy (slist);
		sp_selection_bbox (selection, &b);
		mp.x = mx0 * b.x0 + mx1 * b.x1;
		mp.y = my0 * b.y0 + my1 * b.y1;
		break;
	default:
		g_assert_not_reached ();
		break;
	};

	changed = FALSE;

	for (l = slist; l != NULL; l = l->next) {
		item = (SPItem *) l->data;
		sp_item_bbox_desktop (item, &b);
		sp.x = sx0 * b.x0 + sx1 * b.x1;
		sp.y = sy0 * b.y0 + sy1 * b.y1;

		if ((fabs (mp.x - sp.x) > 1e-9) || (fabs (mp.y - sp.y) > 1e-9)) {
			sp_item_move_rel (item, mp.x - sp.x, mp.y - sp.y);
			changed = TRUE;
		}
	}

	g_slist_free (slist);

	if (changed) {
		sp_selection_changed (selection);
		sp_document_done (SP_DT_DOCUMENT (desktop));
	}
}