void gr_read_selection (Inkscape::Selection *selection, GrDrag *drag, SPGradient **gr_selected, bool *gr_multi, SPGradientSpread *spr_selected, bool *spr_multi) { if (drag && drag->selected) { // GRADIENTFIXME: make this work for more than one selected dragger? GrDragger *dragger = (GrDragger*) drag->selected->data; for (GSList const* i = dragger->draggables; i != NULL; i = i->next) { // for all draggables of dragger GrDraggable *draggable = (GrDraggable *) i->data; SPGradient *gradient = sp_item_gradient_get_vector (draggable->item, draggable->fill_or_stroke); SPGradientSpread spread = sp_item_gradient_get_spread (draggable->item, draggable->fill_or_stroke); if (gradient != *gr_selected) { if (*gr_selected != NULL) { *gr_multi = true; } else { *gr_selected = gradient; } } if (spread != *spr_selected) { if (*spr_selected != INT_MAX) { *spr_multi = true; } else { *spr_selected = spread; } } } return; } // If no selected dragger, read desktop selection for (GSList const* i = selection->itemList(); i != NULL; i = i->next) { SPItem *item = SP_ITEM(i->data); SPStyle *style = SP_OBJECT_STYLE (item); if (style && (style->fill.isPaintserver())) { SPObject *server = SP_OBJECT_STYLE_FILL_SERVER (item); if (SP_IS_GRADIENT (server)) { SPGradient *gradient = sp_gradient_get_vector (SP_GRADIENT (server), false); SPGradientSpread spread = sp_gradient_get_spread (SP_GRADIENT (server)); if (gradient != *gr_selected) { if (*gr_selected != NULL) { *gr_multi = true; } else { *gr_selected = gradient; } } if (spread != *spr_selected) { if (*spr_selected != INT_MAX) { *spr_multi = true; } else { *spr_selected = spread; } } } } if (style && (style->stroke.isPaintserver())) { SPObject *server = SP_OBJECT_STYLE_STROKE_SERVER (item); if (SP_IS_GRADIENT (server)) { SPGradient *gradient = sp_gradient_get_vector (SP_GRADIENT (server), false); SPGradientSpread spread = sp_gradient_get_spread (SP_GRADIENT (server)); if (gradient != *gr_selected) { if (*gr_selected != NULL) { *gr_multi = true; } else { *gr_selected = gradient; } } if (spread != *spr_selected) { if (*spr_selected != INT_MAX) { *spr_multi = true; } else { *spr_selected = spread; } } } } } }
static void sp_fill_style_widget_update (SPWidget *spw, SPSelection *sel) { SPPaintSelector *psel; GtkWidget *fillrule; SPPaintSelectorMode pselmode; const GSList *objects, *l; SPObject *object; SPGradient *vector; gfloat c[5]; SPLinearGradient *lg; SPRadialGradient *rg; #if 0 NRPointF p0, p1, p2; #endif NRMatrixF fctm, gs2d; NRRectF fbb; if (g_object_get_data (G_OBJECT (spw), "update")) return; g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (TRUE)); psel = SP_PAINT_SELECTOR (g_object_get_data (G_OBJECT (spw), "paint-selector")); if (!sel || sp_selection_is_empty (sel)) { /* No objects, set empty */ sp_paint_selector_set_mode (psel, SP_PAINT_SELECTOR_MODE_EMPTY); g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (FALSE)); return; } objects = sp_selection_item_list (sel); object = SP_OBJECT (objects->data); pselmode = (SPPaintSelectorMode)sp_fill_style_determine_paint_selector_mode (SP_OBJECT_STYLE (object)); for (l = objects->next; l != NULL; l = l->next) { SPPaintSelectorMode nextmode; nextmode = sp_fill_style_determine_paint_selector_mode (SP_OBJECT_STYLE (l->data)); if (nextmode != pselmode) { /* Multiple styles */ sp_paint_selector_set_mode (psel, SP_PAINT_SELECTOR_MODE_MULTIPLE); g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (FALSE)); return; } } #ifdef SP_FS_VERBOSE g_print ("FillStyleWidget: paint selector mode %d\n", pselmode); #endif switch (pselmode) { case SP_PAINT_SELECTOR_MODE_NONE: /* No paint at all */ sp_paint_selector_set_mode (psel, SP_PAINT_SELECTOR_MODE_NONE); break; case SP_PAINT_SELECTOR_MODE_COLOR_RGB: sp_paint_selector_set_mode (psel, SP_PAINT_SELECTOR_MODE_COLOR_RGB); sp_fill_style_get_average_color_rgba (objects, c); sp_paint_selector_set_color_rgba_floatv (psel, c); break; case SP_PAINT_SELECTOR_MODE_COLOR_CMYK: sp_paint_selector_set_mode (psel, SP_PAINT_SELECTOR_MODE_COLOR_CMYK); sp_fill_style_get_average_color_cmyka (objects, c); sp_paint_selector_set_color_cmyka_floatv (psel, c); break; case SP_PAINT_SELECTOR_MODE_GRADIENT_LINEAR: object = SP_OBJECT (objects->data); /* We know that all objects have lineargradient fill style */ vector = sp_gradient_get_vector (SP_GRADIENT (SP_OBJECT_STYLE_FILL_SERVER (object)), FALSE); for (l = objects->next; l != NULL; l = l->next) { SPObject *next; next = SP_OBJECT (l->data); if (sp_gradient_get_vector (SP_GRADIENT (SP_OBJECT_STYLE_FILL_SERVER (next)), FALSE) != vector) { /* Multiple vectors */ sp_paint_selector_set_mode (psel, SP_PAINT_SELECTOR_MODE_MULTIPLE); g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (FALSE)); return; } } /* fixme: Probably we should set multiple mode here too */ sp_paint_selector_set_gradient_linear (psel, vector); sp_selection_bbox_document (sel, &fbb); sp_paint_selector_set_gradient_bbox (psel, fbb.x0, fbb.y0, fbb.x1, fbb.y1); /* fixme: This is plain wrong */ lg = SP_LINEARGRADIENT (SP_OBJECT_STYLE_FILL_SERVER (object)); sp_item_invoke_bbox (SP_ITEM (object), &fbb, NULL, TRUE); sp_item_i2doc_affine (SP_ITEM (object), &fctm); sp_gradient_get_gs2d_matrix_f (SP_GRADIENT (lg), &fctm, &fbb, &gs2d); sp_paint_selector_set_gradient_gs2d_matrix_f (psel, &gs2d); sp_paint_selector_set_gradient_properties (psel, SP_GRADIENT_UNITS (lg), SP_GRADIENT_SPREAD (lg)); sp_paint_selector_set_lgradient_position (psel, lg->x1.computed, lg->y1.computed, lg->x2.computed, lg->y2.computed); break; case SP_PAINT_SELECTOR_MODE_GRADIENT_RADIAL: object = SP_OBJECT (objects->data); /* We know that all objects have radialgradient fill style */ vector = sp_gradient_get_vector (SP_GRADIENT (SP_OBJECT_STYLE_FILL_SERVER (object)), FALSE); for (l = objects->next; l != NULL; l = l->next) { SPObject *next; next = SP_OBJECT (l->data); if (sp_gradient_get_vector (SP_GRADIENT (SP_OBJECT_STYLE_FILL_SERVER (next)), FALSE) != vector) { /* Multiple vectors */ sp_paint_selector_set_mode (psel, SP_PAINT_SELECTOR_MODE_MULTIPLE); g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (FALSE)); return; } } /* fixme: Probably we should set multiple mode here too */ sp_paint_selector_set_gradient_radial (psel, vector); sp_selection_bbox_document (sel, &fbb); sp_paint_selector_set_gradient_bbox (psel, fbb.x0, fbb.y0, fbb.x1, fbb.y1); /* fixme: This is plain wrong */ rg = SP_RADIALGRADIENT (SP_OBJECT_STYLE_FILL_SERVER (object)); sp_item_invoke_bbox (SP_ITEM (object), &fbb, NULL, TRUE); sp_item_i2doc_affine (SP_ITEM (object), &fctm); sp_gradient_get_gs2d_matrix_f (SP_GRADIENT (rg), &fctm, &fbb, &gs2d); sp_paint_selector_set_gradient_gs2d_matrix_f (psel, &gs2d); sp_paint_selector_set_gradient_properties (psel, SP_GRADIENT_UNITS (rg), SP_GRADIENT_SPREAD (rg)); sp_paint_selector_set_rgradient_position (psel, rg->cx.computed, rg->cy.computed, rg->fx.computed, rg->fy.computed, rg->r.computed); break; default: sp_paint_selector_set_mode (psel, SP_PAINT_SELECTOR_MODE_MULTIPLE); break; } fillrule = GTK_WIDGET(g_object_get_data (G_OBJECT (spw), "fill-rule")); gtk_option_menu_set_history (GTK_OPTION_MENU (fillrule), (SP_OBJECT_STYLE (object)->fill_rule.computed == ART_WIND_RULE_NONZERO) ? 0 : 1); g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (FALSE)); }