Code

fd8f46e0441611eac9c9810d7b932ba201826e58
[inkscape.git] / filter-effect-chooser.cpp
1 /*
2  * Filter effect selection selection widget
3  *
4  * Author:
5  *   Nicholas Bishop <nicholasbishop@gmail.com>
6  *
7  * Copyright (C) 2007 Authors
8  *
9  * Released under GNU GPL, read the file 'COPYING' for more information
10  */
12 #include <glibmm/i18n.h>
14 #include "desktop.h"
15 #include "desktop-handles.h"
16 #include "document.h"
17 #include "filter-effect-chooser.h"
18 #include "inkscape.h"
19 #include "ui/dialog/dialog-manager.h"
21 namespace Inkscape {
22 namespace UI {
23 namespace Widget {
25 FilterEffectChooser::FilterEffectChooser()
26 {
27     _model = Gtk::ListStore::create(_columns);
29     g_signal_connect(G_OBJECT(INKSCAPE), "activate_desktop",
30                      G_CALLBACK(&FilterEffectChooser::on_activate_desktop), this);
33     on_activate_desktop(INKSCAPE, SP_ACTIVE_DESKTOP, this);
34 }
36 void FilterEffectChooser::on_activate_desktop(Inkscape::Application*, SPDesktop* desktop, FilterEffectChooser* fec)
37 {
38     fec->update_filters();
40     fec->_doc_replaced.disconnect();
41     fec->_doc_replaced = desktop->connectDocumentReplaced(
42         sigc::mem_fun(fec, &FilterEffectChooser::on_document_replaced));
44     fec->_resource_changed.disconnect();
45     fec->_resource_changed =
46         sp_document_resources_changed_connect(sp_desktop_document(desktop), "filter",
47                                               sigc::mem_fun(fec, &FilterEffectChooser::update_filters));
48 }
50 void FilterEffectChooser::on_document_replaced(SPDesktop* desktop, SPDocument* document)
51 {
52     update_filters();
53 }
55 /* Add all filters in the document to the combobox.
56    Keeps the same selection if possible, otherwise selects the first element */
57 void FilterEffectChooser::update_filters()
58 {
59     SPDesktop* desktop = SP_ACTIVE_DESKTOP;
60     SPDocument* document = sp_desktop_document(desktop);
61     const GSList* filters = sp_document_get_resource_list(document, "filter");
63     _model->clear();
65     for(const GSList *l = filters; l; l = l->next) {
66         Gtk::TreeModel::Row row = *_model->append();
67         SPFilter* f = (SPFilter*)l->data;
68         row[_columns.filter] = f;
69         const gchar* id = SP_OBJECT_ID(f);
70         row[_columns.id] = id ? id : "";
71     }
72 }
74 SimpleFilterModifier::SimpleFilterModifier()
75     : _lb_blend(_("_Blend mode:")),
76       _lb_blur(_("B_lur:"), Gtk::ALIGN_LEFT),
77       _lb_filter(_("F_ilter:"), Gtk::ALIGN_LEFT),
78       _blend(BlendModeConverter),
79       _blur(0, 0, 100, 1, 0.01, 1),
80       _edit_filters(_("_Edit"))
81 {
82     add(_hb_blend);
83     add(_vb_blur);
84     add(_hb_filter);
85     _hb_blend.pack_start(_lb_blend, false, false);
86     _hb_blend.pack_start(_blend);
87     _vb_blur.add(_lb_blur);
88     _vb_blur.add(_blur);
89     _hb_filter.pack_start(_lb_filter, false, false);
90     _hb_filter.pack_start(_hb_filter_sub);
91     _hb_filter_sub.add(_filter);
92     _hb_filter_sub.add(_edit_filters);
94     show_all_children();
96     signal_show().connect(sigc::mem_fun(*this, &SimpleFilterModifier::blend_mode_changed));
97     _hb_blend.set_spacing(12);
98     _hb_filter.set_spacing(12);
99     _lb_blend.set_use_underline();
100     _lb_blend.set_mnemonic_widget(_blend);
101     _lb_blur.set_use_underline();
102     _lb_blur.set_mnemonic_widget(_blur.get_scale());
103     _lb_filter.set_use_underline();
104     _lb_filter.set_mnemonic_widget(_filter);
105     _blend.add_row("Filter");
106     _blend.signal_changed().connect(sigc::mem_fun(*this, &SimpleFilterModifier::blend_mode_changed));
107     _blend.signal_changed().connect(signal_blend_blur_changed());
108     _blur.signal_value_changed().connect(signal_blend_blur_changed());
109     _filter.set_model(_model);
110     _filter.pack_start(_columns.id);
111     _edit_filters.signal_clicked().connect(sigc::mem_fun(*this, &SimpleFilterModifier::show_filter_dialog));
112     _edit_filters.set_use_underline();
114     update_filters();
117 Glib::SignalProxy0<void> SimpleFilterModifier::signal_selection_changed()
119     return _filter.signal_changed();
122 SPFilter* SimpleFilterModifier::get_selected_filter()
124     Gtk::TreeModel::iterator i = _filter.get_active();
126     if(i)
127         return (*i)[_columns.filter];
129     return 0;
132 void SimpleFilterModifier::select_filter(const SPFilter* filter)
134     if(filter) {
135         for(Gtk::TreeModel::iterator i = _model->children().begin();
136             i != _model->children().end(); ++i) {
137             if((*i)[_columns.filter] == filter) {
138                 _filter.set_active(i);
139                 break;
140             }
141         }
142     }
145 sigc::signal<void>& SimpleFilterModifier::signal_blend_blur_changed()
147     return _signal_blend_blur_changed;
150 const Glib::ustring SimpleFilterModifier::get_blend_mode()
152     return _blend.get_active_row_number() == 5 ? "filter" : _blend.get_active_data()->name;
155 void SimpleFilterModifier::set_blend_mode(const int val)
157     _blend.set_active(val);
160 double SimpleFilterModifier::get_blur_value() const
162     return _blur.get_value();
165 void SimpleFilterModifier::set_blur_value(const double val)
167     _blur.set_value(val);
170 void SimpleFilterModifier::set_blur_sensitive(const bool s)
172     _blur.set_sensitive(s);
175 void SimpleFilterModifier::update_filters()
177     const SPFilter* active_filter = get_selected_filter();
179     FilterEffectChooser::update_filters();
181     if(_model->children().empty()) {
182         // Set state if no filters exist
183         Gtk::TreeModel::Row row = *_model->prepend();
184         row[_columns.filter] = 0;
185         row[_columns.id] = "None";
186         _filter.set_sensitive(false);
187         _filter.set_active(0);
188     }
189     else {
190         _filter.set_sensitive(true);
191         select_filter(active_filter);
192     }
195 void SimpleFilterModifier::show_filter_dialog()
197     SP_ACTIVE_DESKTOP->_dlg_mgr->showDialog("FilterEffectsDialog");
200 void SimpleFilterModifier::blend_mode_changed()
202     if(_blend.get_active_row_number() == 5) {
203         _vb_blur.hide();
204         _hb_filter.show();
205     }
206     else {
207         _hb_filter.hide();
208         _vb_blur.show();
209     }
212 /*** From filter-effect-enums.h ***/
213 const EnumData<NR::FilterPrimitiveType> FPData[NR::NR_FILTER_ENDPRIMITIVETYPE] = {
214     {NR::NR_FILTER_BLEND,             _("Blend"),              "svg:feBlend"},
215     {NR::NR_FILTER_COLORMATRIX,       _("Color Matrix"),       "svg:feColorMatrix"},
216     {NR::NR_FILTER_COMPONENTTRANSFER, _("Component Transfer"), "svg:feComponentTransfer"},
217     {NR::NR_FILTER_COMPOSITE,         _("Composite"),          "svg:feComposite"},
218     {NR::NR_FILTER_CONVOLVEMATRIX,    _("Convolve Matrix"),    "svg:feConvolveMatrix"},
219     {NR::NR_FILTER_DIFFUSELIGHTING,   _("Diffuse Lighting"),   "svg:feDiffuseLighting"},
220     {NR::NR_FILTER_DISPLACEMENTMAP,   _("Displacement Map"),   "svg:feDisplacementMap"},
221     {NR::NR_FILTER_FLOOD,             _("Flood"),              "svg:feFlood"},
222     {NR::NR_FILTER_GAUSSIANBLUR,      _("Gaussian Blur"),      "svg:feGaussianBlur"},
223     {NR::NR_FILTER_IMAGE,             _("Image"),              "svg:feImage"},
224     {NR::NR_FILTER_MERGE,             _("Merge"),              "svg:feMerge"},
225     {NR::NR_FILTER_MORPHOLOGY,        _("Morphology"),         "svg:feMorphology"},
226     {NR::NR_FILTER_OFFSET,            _("Offset"),             "svg:feOffset"},
227     {NR::NR_FILTER_SPECULARLIGHTING,  _("Specular Lighting"),  "svg:feSpecularLighting"},
228     {NR::NR_FILTER_TILE,              _("Tile"),               "svg:feTile"},
229     {NR::NR_FILTER_TURBULENCE,        _("Turbulence"),         "svg:feTurbulence"}
230 };
231 const Converter<NR::FilterPrimitiveType> FPConverter(FPData, NR::NR_FILTER_ENDPRIMITIVETYPE);
232 const EnumData<NR::FilterBlendMode> BlendModeData[NR::BLEND_ENDMODE] = {
233     {NR::BLEND_NORMAL, _("Normal"), "normal"},
234     {NR::BLEND_MULTIPLY, _("Multiply"), "multiply"},
235     {NR::BLEND_SCREEN, _("Screen"), "screen"},
236     {NR::BLEND_DARKEN, _("Darken"), "darken"},
237     {NR::BLEND_LIGHTEN, _("Lighten"), "lighten"}
238 };
239 const Converter<NR::FilterBlendMode> BlendModeConverter(BlendModeData, NR::BLEND_ENDMODE);
245 /*
246   Local Variables:
247   mode:c++
248   c-file-style:"stroustrup"
249   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
250   indent-tabs-mode:nil
251   fill-column:99
252   End:
253 */
254 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :