diff options
| author | Jabier Arraiza <jabier.arraiza@marker.es> | 2019-10-14 14:25:28 +0000 |
|---|---|---|
| committer | Jabier Arraiza <jabier.arraiza@marker.es> | 2019-10-14 14:25:28 +0000 |
| commit | d58f1115618f0458496b0e0a081238d5fda64ef5 (patch) | |
| tree | 0d87bf8067744160cf824defc783f5ff73935399 /src/ui | |
| parent | Prevent returning references to local variable (diff) | |
| download | inkscape-d58f1115618f0458496b0e0a081238d5fda64ef5.tar.gz inkscape-d58f1115618f0458496b0e0a081238d5fda64ef5.zip | |
Re-Add blending modes UI using CSS instead filters
Diffstat (limited to 'src/ui')
| -rw-r--r-- | src/ui/dialog/fill-and-stroke.cpp | 23 | ||||
| -rw-r--r-- | src/ui/dialog/filter-effects-dialog.h | 2 | ||||
| -rw-r--r-- | src/ui/dialog/objects.cpp | 60 | ||||
| -rw-r--r-- | src/ui/tools/rect-tool.cpp | 4 | ||||
| -rw-r--r-- | src/ui/widget/filter-effect-chooser.cpp | 53 | ||||
| -rw-r--r-- | src/ui/widget/filter-effect-chooser.h | 26 | ||||
| -rw-r--r-- | src/ui/widget/object-composite-settings.cpp | 54 |
7 files changed, 121 insertions, 101 deletions
diff --git a/src/ui/dialog/fill-and-stroke.cpp b/src/ui/dialog/fill-and-stroke.cpp index 2ac87186e..22dd407e7 100644 --- a/src/ui/dialog/fill-and-stroke.cpp +++ b/src/ui/dialog/fill-and-stroke.cpp @@ -41,18 +41,19 @@ namespace UI { namespace Dialog { FillAndStroke::FillAndStroke() - : UI::Widget::Panel("/dialogs/fillstroke", SP_VERB_DIALOG_FILL_STROKE), - _page_fill(Gtk::manage(new UI::Widget::NotebookPage(1, 1, true, true))), - _page_stroke_paint(Gtk::manage(new UI::Widget::NotebookPage(1, 1, true, true))), - _page_stroke_style(Gtk::manage(new UI::Widget::NotebookPage(1, 1, true, true))), - _composite_settings(SP_VERB_DIALOG_FILL_STROKE, "fillstroke", + : UI::Widget::Panel("/dialogs/fillstroke", SP_VERB_DIALOG_FILL_STROKE) + , _page_fill(Gtk::manage(new UI::Widget::NotebookPage(1, 1, true, true))) + , _page_stroke_paint(Gtk::manage(new UI::Widget::NotebookPage(1, 1, true, true))) + , _page_stroke_style(Gtk::manage(new UI::Widget::NotebookPage(1, 1, true, true))) + , _composite_settings(SP_VERB_DIALOG_FILL_STROKE, "fillstroke", + UI::Widget::SimpleFilterModifier::BLEND | UI::Widget::SimpleFilterModifier::BLUR | - UI::Widget::SimpleFilterModifier::OPACITY ), - deskTrack(), - targetDesktop(nullptr), - fillWdgt(nullptr), - strokeWdgt(nullptr), - desktopChangeConn() + UI::Widget::SimpleFilterModifier::OPACITY) + , deskTrack() + , targetDesktop(nullptr) + , fillWdgt(nullptr) + , strokeWdgt(nullptr) + , desktopChangeConn() { Gtk::Box *contents = _getContents(); contents->set_spacing(2); diff --git a/src/ui/dialog/filter-effects-dialog.h b/src/ui/dialog/filter-effects-dialog.h index 6f86df797..5c01a8395 100644 --- a/src/ui/dialog/filter-effects-dialog.h +++ b/src/ui/dialog/filter-effects-dialog.h @@ -23,7 +23,7 @@ #include <gtkmm/scrolledwindow.h> #include "attributes.h" - +#include "display/nr-filter-types.h" #include "ui/dialog/desktop-tracker.h" #include "ui/widget/combo-enums.h" #include "ui/widget/panel.h" diff --git a/src/ui/dialog/objects.cpp b/src/ui/dialog/objects.cpp index e0af43d52..e4655f4a3 100644 --- a/src/ui/dialog/objects.cpp +++ b/src/ui/dialog/objects.cpp @@ -585,20 +585,15 @@ void ObjectsPanel::_setCompositingValues(SPItem *item) double opacity = (item->style->opacity.set ? SP_SCALE24_TO_FLOAT(item->style->opacity.value) : 1); opacity *= 100; // Display in percent. _filter_modifier.set_opacity_value(opacity); - - SPFeBlend *spblend = nullptr; + // Set the blend mode + _filter_modifier.set_blend_mode(item->style->mix_blend_mode.set ? item->style->mix_blend_mode.value + : Inkscape::SP_CSS_BLEND_NORMAL); SPGaussianBlur *spblur = nullptr; if (item->style->getFilter()) { - for (auto& primitive_obj: item->style->getFilter()->children) { if (!SP_IS_FILTER_PRIMITIVE(&primitive_obj)) { break; } - if (SP_IS_FEBLEND(&primitive_obj) && !spblend) { - //Get the blend mode - spblend = SP_FEBLEND(&primitive_obj); - } - if (SP_IS_GAUSSIANBLUR(&primitive_obj) && !spblur) { //Get the blur value spblur = SP_GAUSSIANBLUR(&primitive_obj); @@ -606,9 +601,6 @@ void ObjectsPanel::_setCompositingValues(SPItem *item) } } - //Set the blend mode - _filter_modifier.set_blend_mode(spblend ? spblend->blend_mode : Inkscape::Filters::BLEND_NORMAL); - //Set the blur value double blur_value = 0; if (spblur) { @@ -1634,48 +1626,14 @@ void ObjectsPanel::_blendChangedIter(const Gtk::TreeIter& iter, Glib::ustring bl //Since blur and blend are both filters, we need to set both at the same time SPStyle *style = item->style; g_assert(style != nullptr); - - if (blendmode != "normal") { - gdouble radius = 0; - if (item->style->getFilter()) { - for (auto& primitive: item->style->getFilter()->children) { - if (!SP_IS_FILTER_PRIMITIVE(&primitive)) { - break; - } - // We should read in the current radius and use that! - if (SP_IS_GAUSSIANBLUR(&primitive)) { - Geom::OptRect bbox = item->bounds(SPItem::GEOMETRIC_BBOX); - if (bbox) { - double perimeter = bbox->dimensions()[Geom::X] + bbox->dimensions()[Geom::Y]; // fixme: this is only half the perimeter, is that correct? - radius = _filter_modifier.get_blur_value() * perimeter / 400; - } - } - } - } - if (radius != 0) { - // The modify function expects radius to be in display pixels. - Geom::Affine i2d (item->i2dt_affine()); - double expansion = i2d.descrim(); - radius *= expansion; - } - SPFilter *filter = new_filter_simple_from_item(_document, item, blendmode.c_str(), radius); - sp_style_set_property_url(item, "filter", filter, false); + SPCSSAttr *css = sp_css_attr_from_style(style, SP_STYLE_FLAG_ALWAYS | SP_STYLE_FLAG_IFSRC); + if (blendmode == "normal") { + sp_repr_css_unset_property(css, "mix-blend-mode"); } else { - for (auto& primitive: item->style->getFilter()->children) { - if (!SP_IS_FILTER_PRIMITIVE(&primitive)) { - break; - } - if (SP_IS_FEBLEND(&primitive)) { - primitive.deleteObject(); - break; - } - } - if (!item->style->getFilter()->firstChild()) { - remove_filter(item, false); - } + sp_repr_css_set_property(css, "mix-blend-mode", blendmode.c_str()); } - - item->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); + sp_repr_css_change(item->getRepr(), css, "style"); + sp_repr_css_attr_unref(css); } } diff --git a/src/ui/tools/rect-tool.cpp b/src/ui/tools/rect-tool.cpp index 93f9cb5f8..2cd10a28b 100644 --- a/src/ui/tools/rect-tool.cpp +++ b/src/ui/tools/rect-tool.cpp @@ -462,10 +462,6 @@ void RectTool::finishItem() { this->desktop->getSelection()->set(this->rect); - if (this->rect->hasPathEffectRecursive()) { - this->desktop->getSelection()->toCurves(); - } - DocumentUndo::done(this->desktop->getDocument(), SP_VERB_CONTEXT_RECT, _("Create rectangle")); this->rect = nullptr; diff --git a/src/ui/widget/filter-effect-chooser.cpp b/src/ui/widget/filter-effect-chooser.cpp index aeca506eb..d0c0e388a 100644 --- a/src/ui/widget/filter-effect-chooser.cpp +++ b/src/ui/widget/filter-effect-chooser.cpp @@ -15,15 +15,47 @@ #include "document.h" + +using Inkscape::Util::EnumData; +using Inkscape::Util::EnumDataConverter; + + namespace Inkscape { + +const EnumData<Inkscape::CSSBlendMode> CSSBlendModeData[SP_CSS_BLEND_ENDMODE] = { + { SP_CSS_BLEND_NORMAL, _("Normal"), "normal" }, + { SP_CSS_BLEND_MULTIPLY, _("Multiply"), "multiply" }, + { SP_CSS_BLEND_SCREEN, _("Screen"), "screen" }, + { SP_CSS_BLEND_DARKEN, _("Darken"), "darken" }, + { SP_CSS_BLEND_LIGHTEN, _("Lighten"), "lighten" }, + // New in Compositing and Blending Level 1 + { SP_CSS_BLEND_OVERLAY, _("Overlay"), "overlay" }, + { SP_CSS_BLEND_COLORDODGE, _("Color Dodge"), "color-dodge" }, + { SP_CSS_BLEND_COLORBURN, _("Color Burn"), "color-burn" }, + { SP_CSS_BLEND_HARDLIGHT, _("Hard Light"), "hard-light" }, + { SP_CSS_BLEND_SOFTLIGHT, _("Soft Light"), "soft-light" }, + { SP_CSS_BLEND_DIFFERENCE, _("Difference"), "difference" }, + { SP_CSS_BLEND_EXCLUSION, _("Exclusion"), "exclusion" }, + { SP_CSS_BLEND_HUE, _("Hue"), "hue" }, + { SP_CSS_BLEND_SATURATION, _("Saturation"), "saturation" }, + { SP_CSS_BLEND_COLOR, _("Color"), "color" }, + { SP_CSS_BLEND_LUMINOSITY, _("Luminosity"), "luminosity" } +}; +#ifdef WITH_CSSBLEND +const EnumDataConverter<Inkscape::CSSBlendMode> CSSBlendModeConverter(CSSBlendModeData, SP_CSS_BLEND_ENDMODE); +#else +// Disable new blend modes in GUI until widely implemented. +const EnumDataConverter<Inkscape::CSSBlendMode> CSSBlendModeConverter(CSSBlendModeData, SP_CSS_BLEND_LUMINOSITY); +#endif + namespace UI { namespace Widget { SimpleFilterModifier::SimpleFilterModifier(int flags) - : _flags( flags ) + : _flags(flags) , _lb_blend(_("Blend mode:")) - , _blend(BlendModeConverter, SP_ATTR_INVALID, false) - , _blur( _("Blur (%)" ), 0, 0, 100, 1, 0.1, 1) + , _blend(CSSBlendModeConverter, SP_ATTR_INVALID, false) + , _blur(_("Blur (%)"), 0, 0, 100, 1, 0.1, 1) , _opacity(_("Opacity (%)"), 0, 0, 100, 1, 0.1, 1) { set_name("SimpleFilterModifier"); @@ -33,9 +65,17 @@ SimpleFilterModifier::SimpleFilterModifier(int flags) if (flags & BLEND) { add(_hb_blend); _lb_blend.set_use_underline(); + _hb_blend.set_halign(Gtk::ALIGN_END); + _hb_blend.set_valign(Gtk::ALIGN_CENTER); + _hb_blend.set_margin_top(3); + _hb_blend.set_margin_end(5); _lb_blend.set_mnemonic_widget(_blend); - _hb_blend.pack_start(_lb_blend, false, false, 0); - _hb_blend.pack_start(_blend); + _hb_blend.pack_start(_lb_blend, false, false, 5); + _hb_blend.pack_start(_blend, false, false, 5); + Gtk::Separator *separator = Gtk::manage(new Gtk::Separator()); + separator->set_margin_top(8); + separator->set_margin_bottom(8); + add(*separator); } if (flags & BLUR) { @@ -45,7 +85,6 @@ SimpleFilterModifier::SimpleFilterModifier(int flags) if (flags & OPACITY) { add(_opacity); } - show_all_children(); _blend.signal_changed().connect(signal_blend_changed()); @@ -70,7 +109,7 @@ sigc::signal<void>& SimpleFilterModifier::signal_opacity_changed() const Glib::ustring SimpleFilterModifier::get_blend_mode() { - const Util::EnumData<Inkscape::Filters::FilterBlendMode> *d = _blend.get_active_data(); + const Util::EnumData<Inkscape::CSSBlendMode> *d = _blend.get_active_data(); if (d) { return _blend.get_active_data()->key; } else diff --git a/src/ui/widget/filter-effect-chooser.h b/src/ui/widget/filter-effect-chooser.h index 054fac242..c27d82888 100644 --- a/src/ui/widget/filter-effect-chooser.h +++ b/src/ui/widget/filter-effect-chooser.h @@ -16,12 +16,34 @@ #include <gtkmm/box.h> #include <gtkmm/combobox.h> +#include <gtkmm/separator.h> #include "combo-enums.h" -#include "filter-enums.h" #include "spin-scale.h" +#include "style-enums.h" namespace Inkscape { +enum CSSBlendMode { + SP_CSS_BLEND_NORMAL, + SP_CSS_BLEND_MULTIPLY, + SP_CSS_BLEND_SCREEN, + SP_CSS_BLEND_DARKEN, + SP_CSS_BLEND_LIGHTEN, + // New in CSS Compositing and Blending Level 1 + SP_CSS_BLEND_OVERLAY, + SP_CSS_BLEND_COLORDODGE, + SP_CSS_BLEND_COLORBURN, + SP_CSS_BLEND_HARDLIGHT, + SP_CSS_BLEND_SOFTLIGHT, + SP_CSS_BLEND_DIFFERENCE, + SP_CSS_BLEND_EXCLUSION, + SP_CSS_BLEND_HUE, + SP_CSS_BLEND_SATURATION, + SP_CSS_BLEND_COLOR, + SP_CSS_BLEND_LUMINOSITY, + SP_CSS_BLEND_ENDMODE, +}; + namespace UI { namespace Widget { @@ -59,7 +81,7 @@ private: Gtk::HBox _hb_blend; Gtk::Label _lb_blend; - ComboBoxEnum<Inkscape::Filters::FilterBlendMode> _blend; + ComboBoxEnum<Inkscape::CSSBlendMode> _blend; SpinScale _blur; SpinScale _opacity; diff --git a/src/ui/widget/object-composite-settings.cpp b/src/ui/widget/object-composite-settings.cpp index 6e37c095b..4052e1d38 100644 --- a/src/ui/widget/object-composite-settings.cpp +++ b/src/ui/widget/object-composite-settings.cpp @@ -113,13 +113,18 @@ ObjectCompositeSettings::_blendBlurValueChanged() SPStyle *style = item->style; g_assert(style != nullptr); - if (blendmode != "normal") { - SPFilter *filter = new_filter_simple_from_item(document, item, blendmode.c_str(), radius); - sp_style_set_property_url(item, "filter", filter, false); + SPCSSAttr *css = sp_repr_css_attr_new(); + + if (blendmode == "normal") { + sp_repr_css_unset_property(css, "mix-blend-mode"); } else { - sp_style_set_property_url(item, "filter", nullptr, false); + sp_repr_css_set_property(css, "mix-blend-mode", blendmode.c_str()); } + _subject->setCSS(css); + + sp_repr_css_attr_unref(css); + if (radius == 0 && item->style->filter.set && filter_is_single_gaussian_blur(SP_FILTER(item->style->getFilter()))) { remove_filter(item, false); @@ -192,7 +197,6 @@ ObjectCompositeSettings::_subjectChanged() { if (_blocked) return; _blocked = true; - SPStyle query(desktop->getDocument()); int result = _subject->queryStyle(&query, QUERY_STYLE_PROPERTY_MASTEROPACITY); @@ -213,32 +217,32 @@ ObjectCompositeSettings::_subjectChanged() { break; case QUERY_STYLE_SINGLE: case QUERY_STYLE_MULTIPLE_SAME: - _filter_modifier.set_blend_mode(query.filter_blend_mode.value); + _filter_modifier.set_blend_mode(query.mix_blend_mode.value); // here dont work mix_blend_mode.set break; case QUERY_STYLE_MULTIPLE_DIFFERENT: // TODO: set text break; } - if(blend_result == QUERY_STYLE_SINGLE || blend_result == QUERY_STYLE_MULTIPLE_SAME) { - int blur_result = _subject->queryStyle(&query, QUERY_STYLE_PROPERTY_BLUR); - switch (blur_result) { - case QUERY_STYLE_NOTHING: //no blurring - _filter_modifier.set_blur_value(0); - break; - case QUERY_STYLE_SINGLE: - case QUERY_STYLE_MULTIPLE_AVERAGED: - case QUERY_STYLE_MULTIPLE_SAME: - Geom::OptRect bbox = _subject->getBounds(SPItem::GEOMETRIC_BBOX); - if (bbox) { - double perimeter = bbox->dimensions()[Geom::X] + bbox->dimensions()[Geom::Y]; // fixme: this is only half the perimeter, is that correct? - //update blur widget value - float radius = query.filter_gaussianBlur_deviation.value; - float percent = radius * 400 / perimeter; // so that for a square, 100% == half side - _filter_modifier.set_blur_value(percent); - } - break; - } + int blur_result = _subject->queryStyle(&query, QUERY_STYLE_PROPERTY_BLUR); + switch (blur_result) { + case QUERY_STYLE_NOTHING: // no blurring + _filter_modifier.set_blur_value(0); + break; + case QUERY_STYLE_SINGLE: + case QUERY_STYLE_MULTIPLE_AVERAGED: + case QUERY_STYLE_MULTIPLE_SAME: + Geom::OptRect bbox = _subject->getBounds(SPItem::GEOMETRIC_BBOX); + if (bbox) { + double perimeter = + bbox->dimensions()[Geom::X] + + bbox->dimensions()[Geom::Y]; // fixme: this is only half the perimeter, is that correct? + // update blur widget value + float radius = query.filter_gaussianBlur_deviation.value; + float percent = radius * 400 / perimeter; // so that for a square, 100% == half side + _filter_modifier.set_blur_value(percent); + } + break; } // If we have nothing selected, disable dialog. |
