fill-style.cpp revision 0c13cd8bc2121c9e2e1850899d4bda2cd85840ca
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * @brief Fill style widget
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Lauris Kaplinski <lauris@kaplinski.com>
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Frank Felfe <innerspace@iname.com>
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * bulia byak <buliabyak@users.sf.net>
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Copyright (C) 1999-2005 authors
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Copyright (C) 2001-2002 Ximian, Inc.
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Released under GNU GPL, read the file 'COPYING' for more information
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh// These can be deleted once we sort out the libart dependence.
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshstatic void sp_fill_style_widget_construct ( SPWidget *spw,
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshstatic void sp_fill_style_widget_modify_selection ( SPWidget *spw,
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshstatic void sp_fill_style_widget_change_subselection ( Inkscape::Application *inkscape, SPDesktop *desktop, SPWidget *spw );
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshstatic void sp_fill_style_widget_change_selection ( SPWidget *spw,
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshstatic void sp_fill_style_widget_update (SPWidget *spw);
5c45c5153b0415f7573f69f4ee3e946b5872a8d1theadibstatic void sp_fill_style_widget_paint_mode_changed( SPPaintSelector *psel,
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshstatic void sp_fill_style_widget_fillrule_changed( SPPaintSelector *psel,
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshstatic void sp_fill_style_widget_paint_dragged (SPPaintSelector *psel, SPWidget *spw );
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshstatic void sp_fill_style_widget_paint_changed (SPPaintSelector *psel, SPWidget *spw );
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh GtkWidget *psel = sp_paint_selector_new (true); // with fillrule selector
63d6ddd517060979dd8b8fd41aad3faca7be3c5cTed Gould gtk_box_pack_start (GTK_BOX (vb), psel, TRUE, TRUE, 0);
63d6ddd517060979dd8b8fd41aad3faca7be3c5cTed Gould g_object_set_data (G_OBJECT (spw), "paint-selector", psel);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh G_CALLBACK (sp_fill_style_widget_paint_mode_changed),
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh g_signal_connect ( G_OBJECT (psel), "fillrule_changed",
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh//FIXME: switch these from spw signals to global inkscape object signals; spw just retranslates
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh//those anyway; then eliminate spw
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh g_signal_connect ( G_OBJECT (spw), "modify_selection",
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh G_CALLBACK (sp_fill_style_widget_modify_selection), psel);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh g_signal_connect ( G_OBJECT (spw), "change_selection",
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh G_CALLBACK (sp_fill_style_widget_change_selection), psel);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh g_signal_connect (INKSCAPE, "change_subselection", G_CALLBACK (sp_fill_style_widget_change_subselection), spw);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh} // end of sp_fill_style_widget_new()
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshsp_fill_style_widget_construct( SPWidget *spw, SPPaintSelector */*psel*/ )
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh g_print ( "Fill style widget constructed: inkscape %p\n",
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh} // end of sp_fill_style_widget_construct()
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshsp_fill_style_widget_modify_selection( SPWidget *spw,
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh g_message("sp_fill_style_widget_modify_selection()");
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshsp_fill_style_widget_change_subselection( Inkscape::Application */*inkscape*/,
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshsp_fill_style_widget_change_selection( SPWidget *spw,
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh* \param sel Selection to use, or NULL.
c87a66337fedd13cf951d99e604362432220deb5johanengelen if (g_object_get_data (G_OBJECT (spw), "update"))
54e660c4de9d37185e3953165d053526632ef4f0johanengelen if (g_object_get_data (G_OBJECT (spw), "local")) {
54e660c4de9d37185e3953165d053526632ef4f0johanengelen g_object_set_data (G_OBJECT (spw), "local", GINT_TO_POINTER (FALSE)); // local change; do nothing, but reset the flag
e9b6af083e34e2397a8ddbe9781920733d09d151Ted Gould g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (TRUE));
e9b6af083e34e2397a8ddbe9781920733d09d151Ted Gould SPPaintSelector *psel = SP_PAINT_SELECTOR (g_object_get_data (G_OBJECT (spw), "paint-selector"));
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh // create temporary style
7079a43aa387066c2f67402d77dbe3db981b1054Ted Gould SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT);
54e660c4de9d37185e3953165d053526632ef4f0johanengelen // query style from desktop into it. This returns a result flag and fills query with the style of subselection, if any, or selection
7079a43aa387066c2f67402d77dbe3db981b1054Ted Gould int result = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FILL);
54e660c4de9d37185e3953165d053526632ef4f0johanengelen /* No paint at all */
7079a43aa387066c2f67402d77dbe3db981b1054Ted Gould case QUERY_STYLE_MULTIPLE_AVERAGED: // TODO: treat this slightly differently, e.g. display "averaged" somewhere in paint selector
54e660c4de9d37185e3953165d053526632ef4f0johanengelen SPPaintSelector::Mode pselmode = SPPaintSelector::getModeForStyle(*query, true);
54e660c4de9d37185e3953165d053526632ef4f0johanengelen psel->setFillrule(query->fill_rule.computed == ART_WIND_RULE_NONZERO?
54e660c4de9d37185e3953165d053526632ef4f0johanengelen SPPaintSelector::FILLRULE_NONZERO : SPPaintSelector::FILLRULE_EVENODD);
54e660c4de9d37185e3953165d053526632ef4f0johanengelen if (query->fill.set && query->fill.isColor()) {
54e660c4de9d37185e3953165d053526632ef4f0johanengelen psel->setColorAlpha(query->fill.value.color, SP_SCALE24_TO_FLOAT(query->fill_opacity.value));
54e660c4de9d37185e3953165d053526632ef4f0johanengelen } else if (query->fill.set && query->fill.isPaintserver()) {
54e660c4de9d37185e3953165d053526632ef4f0johanengelen SPPaintServer *server = query->getFillPaintServer();
54e660c4de9d37185e3953165d053526632ef4f0johanengelen if (server && SP_IS_GRADIENT(server) && SP_GRADIENT(server)->getVector()->isSwatch()) {
54e660c4de9d37185e3953165d053526632ef4f0johanengelen SPGradient *vector = SP_GRADIENT(server)->getVector();
e9b6af083e34e2397a8ddbe9781920733d09d151Ted Gould SPGradient *vector = SP_GRADIENT(server)->getVector();
e9b6af083e34e2397a8ddbe9781920733d09d151Ted Gould SPLinearGradient *lg = SP_LINEARGRADIENT (server);
7079a43aa387066c2f67402d77dbe3db981b1054Ted Gould SPGradient *vector = SP_GRADIENT(server)->getVector();
7079a43aa387066c2f67402d77dbe3db981b1054Ted Gould SPRadialGradient *rg = SP_RADIALGRADIENT (server);
7079a43aa387066c2f67402d77dbe3db981b1054Ted Gould psel->setGradientProperties( SP_GRADIENT_UNITS (rg),
7079a43aa387066c2f67402d77dbe3db981b1054Ted Gould SPPattern *pat = pattern_getroot (SP_PATTERN (server));
54e660c4de9d37185e3953165d053526632ef4f0johanengelen g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (FALSE));
e21d4ac16bee82a55fd227660aa14af10ecac9b1johanengelensp_fill_style_widget_paint_mode_changed( SPPaintSelector *psel,
e9b6af083e34e2397a8ddbe9781920733d09d151Ted Gould g_message("sp_fill_style_widget_paint_mode_changed(psel:%p, mode, spw:%p)", psel, spw);
54e660c4de9d37185e3953165d053526632ef4f0johanengelen /* TODO: Does this work? */
7079a43aa387066c2f67402d77dbe3db981b1054Ted Gould /* TODO: Not really, here we have to get old color back from object */
7079a43aa387066c2f67402d77dbe3db981b1054Ted Gould /* Instead of relying on paint widget having meaningful colors set */
54e660c4de9d37185e3953165d053526632ef4f0johanengelenstatic void sp_fill_style_widget_fillrule_changed( SPPaintSelector */*psel*/,
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh sp_repr_css_set_property(css, "fill-rule", mode == SPPaintSelector::FILLRULE_EVENODD? "evenodd":"nonzero");
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh sp_document_done (SP_ACTIVE_DOCUMENT, SP_VERB_DIALOG_FILL_STROKE,
63d6ddd517060979dd8b8fd41aad3faca7be3c5cTed Gould _("Change fill rule"));
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshstatic gchar const *undo_label_1 = "fill:flatcolor:1";
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshstatic gchar const *undo_label_2 = "fill:flatcolor:2";
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshThis is called repeatedly while you are dragging a color slider, only for flat color
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshmodes. Previously it set the color in style but did not update the repr for efficiency, however
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshthis was flakey and didn't buy us almost anything. So now it does the same as _changed, except
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshlumps all its changes for undo.
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshsp_fill_style_widget_paint_dragged (SPPaintSelector *psel, SPWidget *spw)
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh // previous local flag not cleared yet;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh // this means dragged events come too fast, so we better skip this one to speed up display
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh // (it's safe to do this in any case)
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (TRUE));
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh psel->setFlatColor( SP_ACTIVE_DESKTOP, "fill", "fill-opacity" );
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh sp_document_maybe_done (sp_desktop_document(SP_ACTIVE_DESKTOP), undo_label, SP_VERB_DIALOG_FILL_STROKE,
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh _("Set fill color"));
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh g_object_set_data (G_OBJECT (spw), "local", GINT_TO_POINTER (TRUE)); // local change, do not update from selection
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh g_warning ( "file %s: line %d: Paint %d should not emit 'dragged'",
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (FALSE));
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshThis is called (at least) when:
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh1 paint selector mode is switched (e.g. flat color -> gradient)
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh2 you finished dragging a gradient node and released mouse
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh3 you changed a gradient selector parameter (e.g. spread)
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshMust update repr.
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshsp_fill_style_widget_paint_changed ( SPPaintSelector *psel,
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh g_message("sp_fill_style_widget_paint_changed(psel:%p, spw:%p)", psel, spw);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (TRUE));
17d87f5698f5c2958d38c6a6207c7b322a7adaf9johanengelen SPDocument *document = sp_desktop_document (desktop);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh Inkscape::Selection *selection = sp_desktop_selection (desktop);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh // This should not happen.
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh g_warning ( "file %s: line %d: Paint %d should not emit 'changed'",
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh // This happens when you switch multiple objects with different gradients to flat color;
4b1c2be41ce8c1a88502c1b1885ad1468646fbfftheadib // nothing to do here.
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh sp_document_done (document, SP_VERB_DIALOG_FILL_STROKE,
4b1c2be41ce8c1a88502c1b1885ad1468646fbfftheadib _("Remove fill"));
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh // FIXME: fix for GTK breakage, see comment in SelectedStyle::on_opacity_changed; here it results in losing release events
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh sp_canvas_force_full_redraw_after_interruptions(sp_desktop_canvas(desktop), 0);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh psel->setFlatColor( desktop, "fill", "fill-opacity" );
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh sp_document_maybe_done (sp_desktop_document(desktop), undo_label, SP_VERB_DIALOG_FILL_STROKE,
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh _("Set fill color"));
4b1c2be41ce8c1a88502c1b1885ad1468646fbfftheadib // resume interruptibility
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh sp_canvas_end_forced_full_redraws(sp_desktop_canvas(desktop));
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh // on release, toggle undo_label so that the next drag will not be lumped with this one
17d87f5698f5c2958d38c6a6207c7b322a7adaf9johanengelen SPGradientType const gradient_type = ( psel->mode != SPPaintSelector::MODE_GRADIENT_RADIAL
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh // HACK: reset fill-opacity - that 0.75 is annoying; BUT remove this when we have an opacity slider for all tabs
63d6ddd517060979dd8b8fd41aad3faca7be3c5cTed Gould sp_repr_css_set_property(css, "fill-opacity", "1.0");
5c45c5153b0415f7573f69f4ee3e946b5872a8d1theadib /* No vector in paint selector should mean that we just changed mode */
63d6ddd517060979dd8b8fd41aad3faca7be3c5cTed Gould SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT);
5c45c5153b0415f7573f69f4ee3e946b5872a8d1theadib int result = objects_query_fillstroke ((GSList *) items, query, true);
861fa436e7a6d6ff3eaa889b2298e0b82a0b238ctheadib common_rgb = query->fill.value.color.toRGBA32( 0xff );
861fa436e7a6d6ff3eaa889b2298e0b82a0b238ctheadib vector = sp_document_default_gradient_vector(document, common_rgb);
6c3e745a94ef6b25a4ef9f018d350a7535aa45afTed Gould for (GSList const *i = items; i != NULL; i = i->next) {
3bd80e038b72ad220f218d7053a9089685fab17cTed Gould //FIXME: see above
3bd80e038b72ad220f218d7053a9089685fab17cTed Gould sp_repr_css_change_recursive(SP_OBJECT_REPR(i->data), css, "style");
5c45c5153b0415f7573f69f4ee3e946b5872a8d1theadib sp_gradient_vector_for_object(document, desktop, SP_OBJECT(i->data), true),
479ed85bac2b7467a6678bae572404e33465a5d9acspike sp_item_set_gradient(SP_ITEM(i->data), vector, gradient_type, true);
5c45c5153b0415f7573f69f4ee3e946b5872a8d1theadib /* We have changed from another gradient type, or modified spread/units within
63d6ddd517060979dd8b8fd41aad3faca7be3c5cTed Gould * this gradient type. */
3bd80e038b72ad220f218d7053a9089685fab17cTed Gould vector = sp_gradient_ensure_vector_normalized (vector);
3bd80e038b72ad220f218d7053a9089685fab17cTed Gould for (GSList const *i = items; i != NULL; i = i->next) {
63d6ddd517060979dd8b8fd41aad3faca7be3c5cTed Gould //FIXME: see above
63d6ddd517060979dd8b8fd41aad3faca7be3c5cTed Gould sp_repr_css_change_recursive (SP_OBJECT_REPR (i->data), css, "style");
5c45c5153b0415f7573f69f4ee3e946b5872a8d1theadib SPGradient *gr = sp_item_set_gradient(SP_ITEM(i->data), vector, gradient_type, true);
63d6ddd517060979dd8b8fd41aad3faca7be3c5cTed Gould sp_document_done (document, SP_VERB_DIALOG_FILL_STROKE,
63d6ddd517060979dd8b8fd41aad3faca7be3c5cTed Gould _("Set gradient on fill"));
63d6ddd517060979dd8b8fd41aad3faca7be3c5cTed Gould /* No Pattern in paint selector should mean that we just
45d0b0d0dc24df8e321cbe8a085ab9b1f60b4a42theadib * changed mode - dont do jack.
5c45c5153b0415f7573f69f4ee3e946b5872a8d1theadib Inkscape::XML::Node *patrepr = SP_OBJECT_REPR(pattern);
5c45c5153b0415f7573f69f4ee3e946b5872a8d1theadib gchar *urltext = g_strdup_printf ("url(#%s)", patrepr->attribute("id"));
5c45c5153b0415f7573f69f4ee3e946b5872a8d1theadib // HACK: reset fill-opacity - that 0.75 is annoying; BUT remove this when we have an opacity slider for all tabs
63d6ddd517060979dd8b8fd41aad3faca7be3c5cTed Gould sp_repr_css_set_property(css, "fill-opacity", "1.0");
5c45c5153b0415f7573f69f4ee3e946b5872a8d1theadib // cannot just call sp_desktop_set_style, because we don't want to touch those
5c45c5153b0415f7573f69f4ee3e946b5872a8d1theadib // objects who already have the same root pattern but through a different href
5c45c5153b0415f7573f69f4ee3e946b5872a8d1theadib // chain. FIXME: move this to a sp_item_set_pattern
5c45c5153b0415f7573f69f4ee3e946b5872a8d1theadib for (GSList const *i = items; i != NULL; i = i->next) {
1babefb17e4c8157ca2a0f588625a8ac0258dc53buliabyak SPObject *server = SP_OBJECT_STYLE_FILL_SERVER (selobj);
1babefb17e4c8157ca2a0f588625a8ac0258dc53buliabyak if (SP_IS_PATTERN (server) && pattern_getroot (SP_PATTERN(server)) == pattern)
1babefb17e4c8157ca2a0f588625a8ac0258dc53buliabyak // only if this object's pattern is not rooted in our selected pattern, apply
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh } // end if
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh sp_document_done (document, SP_VERB_DIALOG_FILL_STROKE,
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh _("Set pattern on fill"));
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh } // end if
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh sp_document_done (document, SP_VERB_DIALOG_FILL_STROKE,
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh _("Unset fill"));
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh g_warning ( "file %s: line %d: Paint selector should not be in "
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (FALSE));
bf7069a487ba218c4542e4adc5497ebd746ab929buliabyak Local Variables:
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh c-file-style:"stroustrup"
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh indent-tabs-mode:nil
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh fill-column:99
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :