06a6e833e10802fba971d1f028d19c16738597af
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 FilterEffectChooser::~FilterEffectChooser()
37 {
38 _resource_changed.disconnect();
39 _doc_replaced.disconnect();
40 }
42 void FilterEffectChooser::on_activate_desktop(Inkscape::Application*, SPDesktop* desktop, FilterEffectChooser* fec)
43 {
44 fec->update_filters();
46 fec->_doc_replaced.disconnect();
47 fec->_doc_replaced = desktop->connectDocumentReplaced(
48 sigc::mem_fun(fec, &FilterEffectChooser::on_document_replaced));
50 fec->_resource_changed.disconnect();
51 fec->_resource_changed =
52 sp_document_resources_changed_connect(sp_desktop_document(desktop), "filter",
53 sigc::mem_fun(fec, &FilterEffectChooser::update_filters));
54 }
56 void FilterEffectChooser::on_document_replaced(SPDesktop* desktop, SPDocument* document)
57 {
58 update_filters();
59 }
61 /* Add all filters in the document to the combobox.
62 Keeps the same selection if possible, otherwise selects the first element */
63 void FilterEffectChooser::update_filters()
64 {
65 SPDesktop* desktop = SP_ACTIVE_DESKTOP;
66 SPDocument* document = sp_desktop_document(desktop);
67 const GSList* filters = sp_document_get_resource_list(document, "filter");
69 _model->clear();
71 for(const GSList *l = filters; l; l = l->next) {
72 Gtk::TreeModel::Row row = *_model->append();
73 SPFilter* f = (SPFilter*)l->data;
74 row[_columns.filter] = f;
75 const gchar* id = SP_OBJECT_ID(f);
76 row[_columns.id] = id ? id : "";
77 }
78 }
80 SimpleFilterModifier::SimpleFilterModifier()
81 : _lb_blend(_("_Blend mode:")),
82 _lb_blur(_("B_lur:"), Gtk::ALIGN_LEFT),
83 _lb_filter(_("F_ilter:"), Gtk::ALIGN_LEFT),
84 _blend(BlendModeConverter),
85 _blur(0, 0, 100, 1, 0.01, 1),
86 _edit_filters(_("_Edit"))
87 {
88 add(_hb_blend);
89 add(_vb_blur);
90 add(_hb_filter);
91 _hb_blend.pack_start(_lb_blend, false, false);
92 _hb_blend.pack_start(_blend);
93 _vb_blur.add(_lb_blur);
94 _vb_blur.add(_blur);
95 _hb_filter.pack_start(_lb_filter, false, false);
96 _hb_filter.pack_start(_hb_filter_sub);
97 _hb_filter_sub.add(_filter);
98 _hb_filter_sub.add(_edit_filters);
100 show_all_children();
102 signal_show().connect(sigc::mem_fun(*this, &SimpleFilterModifier::blend_mode_changed));
103 _hb_blend.set_spacing(12);
104 _hb_filter.set_spacing(12);
105 _lb_blend.set_use_underline();
106 _lb_blend.set_mnemonic_widget(_blend);
107 _lb_blur.set_use_underline();
108 _lb_blur.set_mnemonic_widget(_blur.get_scale());
109 _lb_filter.set_use_underline();
110 _lb_filter.set_mnemonic_widget(_filter);
111 _blend.add_row("Filter");
112 _blend.signal_changed().connect(sigc::mem_fun(*this, &SimpleFilterModifier::blend_mode_changed));
113 _blend.signal_changed().connect(signal_blend_blur_changed());
114 _blur.signal_value_changed().connect(signal_blend_blur_changed());
115 _filter.set_model(_model);
116 _filter.pack_start(_columns.id);
117 _edit_filters.signal_clicked().connect(sigc::mem_fun(*this, &SimpleFilterModifier::show_filter_dialog));
118 _edit_filters.set_use_underline();
120 update_filters();
121 }
123 Glib::SignalProxy0<void> SimpleFilterModifier::signal_selection_changed()
124 {
125 return _filter.signal_changed();
126 }
128 SPFilter* SimpleFilterModifier::get_selected_filter()
129 {
130 Gtk::TreeModel::iterator i = _filter.get_active();
132 if(i)
133 return (*i)[_columns.filter];
135 return 0;
136 }
138 void SimpleFilterModifier::select_filter(const SPFilter* filter)
139 {
140 if(filter) {
141 for(Gtk::TreeModel::iterator i = _model->children().begin();
142 i != _model->children().end(); ++i) {
143 if((*i)[_columns.filter] == filter) {
144 _filter.set_active(i);
145 break;
146 }
147 }
148 }
149 }
151 sigc::signal<void>& SimpleFilterModifier::signal_blend_blur_changed()
152 {
153 return _signal_blend_blur_changed;
154 }
156 const Glib::ustring SimpleFilterModifier::get_blend_mode()
157 {
158 return _blend.get_active_row_number() == 5 ? "filter" : _blend.get_active_data()->name;
159 }
161 void SimpleFilterModifier::set_blend_mode(const int val)
162 {
163 _blend.set_active(val);
164 }
166 double SimpleFilterModifier::get_blur_value() const
167 {
168 return _blur.get_value();
169 }
171 void SimpleFilterModifier::set_blur_value(const double val)
172 {
173 _blur.set_value(val);
174 }
176 void SimpleFilterModifier::set_blur_sensitive(const bool s)
177 {
178 _blur.set_sensitive(s);
179 }
181 void SimpleFilterModifier::update_filters()
182 {
183 const SPFilter* active_filter = get_selected_filter();
185 FilterEffectChooser::update_filters();
187 if(_model->children().empty()) {
188 // Set state if no filters exist
189 Gtk::TreeModel::Row row = *_model->prepend();
190 row[_columns.filter] = 0;
191 row[_columns.id] = "None";
192 _filter.set_sensitive(false);
193 _filter.set_active(0);
194 }
195 else {
196 _filter.set_sensitive(true);
197 select_filter(active_filter);
198 }
199 }
201 void SimpleFilterModifier::show_filter_dialog()
202 {
203 SP_ACTIVE_DESKTOP->_dlg_mgr->showDialog("FilterEffectsDialog");
204 }
206 void SimpleFilterModifier::blend_mode_changed()
207 {
208 if(_blend.get_active_row_number() == 5) {
209 _vb_blur.hide();
210 _hb_filter.show();
211 }
212 else {
213 _hb_filter.hide();
214 _vb_blur.show();
215 }
216 }
218 /*** From filter-effect-enums.h ***/
219 const EnumData<NR::FilterPrimitiveType> FPData[NR::NR_FILTER_ENDPRIMITIVETYPE] = {
220 {NR::NR_FILTER_BLEND, _("Blend"), "svg:feBlend"},
221 {NR::NR_FILTER_COLORMATRIX, _("Color Matrix"), "svg:feColorMatrix"},
222 {NR::NR_FILTER_COMPONENTTRANSFER, _("Component Transfer"), "svg:feComponentTransfer"},
223 {NR::NR_FILTER_COMPOSITE, _("Composite"), "svg:feComposite"},
224 {NR::NR_FILTER_CONVOLVEMATRIX, _("Convolve Matrix"), "svg:feConvolveMatrix"},
225 {NR::NR_FILTER_DIFFUSELIGHTING, _("Diffuse Lighting"), "svg:feDiffuseLighting"},
226 {NR::NR_FILTER_DISPLACEMENTMAP, _("Displacement Map"), "svg:feDisplacementMap"},
227 {NR::NR_FILTER_FLOOD, _("Flood"), "svg:feFlood"},
228 {NR::NR_FILTER_GAUSSIANBLUR, _("Gaussian Blur"), "svg:feGaussianBlur"},
229 {NR::NR_FILTER_IMAGE, _("Image"), "svg:feImage"},
230 {NR::NR_FILTER_MERGE, _("Merge"), "svg:feMerge"},
231 {NR::NR_FILTER_MORPHOLOGY, _("Morphology"), "svg:feMorphology"},
232 {NR::NR_FILTER_OFFSET, _("Offset"), "svg:feOffset"},
233 {NR::NR_FILTER_SPECULARLIGHTING, _("Specular Lighting"), "svg:feSpecularLighting"},
234 {NR::NR_FILTER_TILE, _("Tile"), "svg:feTile"},
235 {NR::NR_FILTER_TURBULENCE, _("Turbulence"), "svg:feTurbulence"}
236 };
237 const Converter<NR::FilterPrimitiveType> FPConverter(FPData, NR::NR_FILTER_ENDPRIMITIVETYPE);
238 const EnumData<NR::FilterBlendMode> BlendModeData[NR::BLEND_ENDMODE] = {
239 {NR::BLEND_NORMAL, _("Normal"), "normal"},
240 {NR::BLEND_MULTIPLY, _("Multiply"), "multiply"},
241 {NR::BLEND_SCREEN, _("Screen"), "screen"},
242 {NR::BLEND_DARKEN, _("Darken"), "darken"},
243 {NR::BLEND_LIGHTEN, _("Lighten"), "lighten"}
244 };
245 const Converter<NR::FilterBlendMode> BlendModeConverter(BlendModeData, NR::BLEND_ENDMODE);
247 }
248 }
249 }
251 /*
252 Local Variables:
253 mode:c++
254 c-file-style:"stroustrup"
255 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
256 indent-tabs-mode:nil
257 fill-column:99
258 End:
259 */
260 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :