fd8f46e0441611eac9c9810d7b932ba201826e58
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();
115 }
117 Glib::SignalProxy0<void> SimpleFilterModifier::signal_selection_changed()
118 {
119 return _filter.signal_changed();
120 }
122 SPFilter* SimpleFilterModifier::get_selected_filter()
123 {
124 Gtk::TreeModel::iterator i = _filter.get_active();
126 if(i)
127 return (*i)[_columns.filter];
129 return 0;
130 }
132 void SimpleFilterModifier::select_filter(const SPFilter* filter)
133 {
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 }
143 }
145 sigc::signal<void>& SimpleFilterModifier::signal_blend_blur_changed()
146 {
147 return _signal_blend_blur_changed;
148 }
150 const Glib::ustring SimpleFilterModifier::get_blend_mode()
151 {
152 return _blend.get_active_row_number() == 5 ? "filter" : _blend.get_active_data()->name;
153 }
155 void SimpleFilterModifier::set_blend_mode(const int val)
156 {
157 _blend.set_active(val);
158 }
160 double SimpleFilterModifier::get_blur_value() const
161 {
162 return _blur.get_value();
163 }
165 void SimpleFilterModifier::set_blur_value(const double val)
166 {
167 _blur.set_value(val);
168 }
170 void SimpleFilterModifier::set_blur_sensitive(const bool s)
171 {
172 _blur.set_sensitive(s);
173 }
175 void SimpleFilterModifier::update_filters()
176 {
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 }
193 }
195 void SimpleFilterModifier::show_filter_dialog()
196 {
197 SP_ACTIVE_DESKTOP->_dlg_mgr->showDialog("FilterEffectsDialog");
198 }
200 void SimpleFilterModifier::blend_mode_changed()
201 {
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 }
210 }
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);
241 }
242 }
243 }
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 :