diff options
| author | MenTaLguY <mental@rydia.net> | 2007-06-24 18:42:18 +0000 |
|---|---|---|
| committer | mental <mental@users.sourceforge.net> | 2007-06-24 18:42:18 +0000 |
| commit | 76c45c245203714154525b3847af05dbd6ec4fb6 (patch) | |
| tree | baa78a89a82b4ee2520f72830f44c6c5d2c23d7f /src/ui/widget | |
| parent | merge OpenFont license support (diff) | |
| download | inkscape-76c45c245203714154525b3847af05dbd6ec4fb6.tar.gz inkscape-76c45c245203714154525b3847af05dbd6ec4fb6.zip | |
initial filter UI code drop from Nick
(bzr r3095)
Diffstat (limited to 'src/ui/widget')
| -rw-r--r-- | src/ui/widget/Makefile_insert | 5 | ||||
| -rw-r--r-- | src/ui/widget/filter-effect-chooser.cpp | 254 | ||||
| -rw-r--r-- | src/ui/widget/filter-effect-chooser.h | 120 | ||||
| -rw-r--r-- | src/ui/widget/filter-effect-enums.h | 156 | ||||
| -rw-r--r-- | src/ui/widget/spin-slider.cpp | 87 | ||||
| -rw-r--r-- | src/ui/widget/spin-slider.h | 64 |
6 files changed, 686 insertions, 0 deletions
diff --git a/src/ui/widget/Makefile_insert b/src/ui/widget/Makefile_insert index 30d52de01..72fb9cfc2 100644 --- a/src/ui/widget/Makefile_insert +++ b/src/ui/widget/Makefile_insert @@ -18,6 +18,9 @@ ui_widget_libuiwidget_a_SOURCES = \ ui/widget/entity-entry.h \ ui/widget/entry.cpp \ ui/widget/entry.h \ + ui/widget/filter-effect-chooser.h \ + ui/widget/filter-effect-chooser.cpp \ + ui/widget/filter-effect-enums.h \ ui/widget/handlebox.cpp \ ui/widget/handlebox.h \ ui/widget/icon-widget.cpp \ @@ -48,6 +51,8 @@ ui_widget_libuiwidget_a_SOURCES = \ ui/widget/scalar.h \ ui/widget/selected-style.h \ ui/widget/selected-style.cpp \ + ui/widget/spin-slider.h \ + ui/widget/spin-slider.cpp \ ui/widget/style-swatch.h \ ui/widget/style-swatch.cpp \ ui/widget/svg-canvas.cpp \ diff --git a/src/ui/widget/filter-effect-chooser.cpp b/src/ui/widget/filter-effect-chooser.cpp new file mode 100644 index 000000000..fd8f46e04 --- /dev/null +++ b/src/ui/widget/filter-effect-chooser.cpp @@ -0,0 +1,254 @@ +/* + * Filter effect selection selection widget + * + * Author: + * Nicholas Bishop <nicholasbishop@gmail.com> + * + * Copyright (C) 2007 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include <glibmm/i18n.h> + +#include "desktop.h" +#include "desktop-handles.h" +#include "document.h" +#include "filter-effect-chooser.h" +#include "inkscape.h" +#include "ui/dialog/dialog-manager.h" + +namespace Inkscape { +namespace UI { +namespace Widget { + +FilterEffectChooser::FilterEffectChooser() +{ + _model = Gtk::ListStore::create(_columns); + + g_signal_connect(G_OBJECT(INKSCAPE), "activate_desktop", + G_CALLBACK(&FilterEffectChooser::on_activate_desktop), this); + + + on_activate_desktop(INKSCAPE, SP_ACTIVE_DESKTOP, this); +} + +void FilterEffectChooser::on_activate_desktop(Inkscape::Application*, SPDesktop* desktop, FilterEffectChooser* fec) +{ + fec->update_filters(); + + fec->_doc_replaced.disconnect(); + fec->_doc_replaced = desktop->connectDocumentReplaced( + sigc::mem_fun(fec, &FilterEffectChooser::on_document_replaced)); + + fec->_resource_changed.disconnect(); + fec->_resource_changed = + sp_document_resources_changed_connect(sp_desktop_document(desktop), "filter", + sigc::mem_fun(fec, &FilterEffectChooser::update_filters)); +} + +void FilterEffectChooser::on_document_replaced(SPDesktop* desktop, SPDocument* document) +{ + update_filters(); +} + +/* Add all filters in the document to the combobox. + Keeps the same selection if possible, otherwise selects the first element */ +void FilterEffectChooser::update_filters() +{ + SPDesktop* desktop = SP_ACTIVE_DESKTOP; + SPDocument* document = sp_desktop_document(desktop); + const GSList* filters = sp_document_get_resource_list(document, "filter"); + + _model->clear(); + + for(const GSList *l = filters; l; l = l->next) { + Gtk::TreeModel::Row row = *_model->append(); + SPFilter* f = (SPFilter*)l->data; + row[_columns.filter] = f; + const gchar* id = SP_OBJECT_ID(f); + row[_columns.id] = id ? id : ""; + } +} + +SimpleFilterModifier::SimpleFilterModifier() + : _lb_blend(_("_Blend mode:")), + _lb_blur(_("B_lur:"), Gtk::ALIGN_LEFT), + _lb_filter(_("F_ilter:"), Gtk::ALIGN_LEFT), + _blend(BlendModeConverter), + _blur(0, 0, 100, 1, 0.01, 1), + _edit_filters(_("_Edit")) +{ + add(_hb_blend); + add(_vb_blur); + add(_hb_filter); + _hb_blend.pack_start(_lb_blend, false, false); + _hb_blend.pack_start(_blend); + _vb_blur.add(_lb_blur); + _vb_blur.add(_blur); + _hb_filter.pack_start(_lb_filter, false, false); + _hb_filter.pack_start(_hb_filter_sub); + _hb_filter_sub.add(_filter); + _hb_filter_sub.add(_edit_filters); + + show_all_children(); + + signal_show().connect(sigc::mem_fun(*this, &SimpleFilterModifier::blend_mode_changed)); + _hb_blend.set_spacing(12); + _hb_filter.set_spacing(12); + _lb_blend.set_use_underline(); + _lb_blend.set_mnemonic_widget(_blend); + _lb_blur.set_use_underline(); + _lb_blur.set_mnemonic_widget(_blur.get_scale()); + _lb_filter.set_use_underline(); + _lb_filter.set_mnemonic_widget(_filter); + _blend.add_row("Filter"); + _blend.signal_changed().connect(sigc::mem_fun(*this, &SimpleFilterModifier::blend_mode_changed)); + _blend.signal_changed().connect(signal_blend_blur_changed()); + _blur.signal_value_changed().connect(signal_blend_blur_changed()); + _filter.set_model(_model); + _filter.pack_start(_columns.id); + _edit_filters.signal_clicked().connect(sigc::mem_fun(*this, &SimpleFilterModifier::show_filter_dialog)); + _edit_filters.set_use_underline(); + + update_filters(); +} + +Glib::SignalProxy0<void> SimpleFilterModifier::signal_selection_changed() +{ + return _filter.signal_changed(); +} + +SPFilter* SimpleFilterModifier::get_selected_filter() +{ + Gtk::TreeModel::iterator i = _filter.get_active(); + + if(i) + return (*i)[_columns.filter]; + + return 0; +} + +void SimpleFilterModifier::select_filter(const SPFilter* filter) +{ + if(filter) { + for(Gtk::TreeModel::iterator i = _model->children().begin(); + i != _model->children().end(); ++i) { + if((*i)[_columns.filter] == filter) { + _filter.set_active(i); + break; + } + } + } +} + +sigc::signal<void>& SimpleFilterModifier::signal_blend_blur_changed() +{ + return _signal_blend_blur_changed; +} + +const Glib::ustring SimpleFilterModifier::get_blend_mode() +{ + return _blend.get_active_row_number() == 5 ? "filter" : _blend.get_active_data()->name; +} + +void SimpleFilterModifier::set_blend_mode(const int val) +{ + _blend.set_active(val); +} + +double SimpleFilterModifier::get_blur_value() const +{ + return _blur.get_value(); +} + +void SimpleFilterModifier::set_blur_value(const double val) +{ + _blur.set_value(val); +} + +void SimpleFilterModifier::set_blur_sensitive(const bool s) +{ + _blur.set_sensitive(s); +} + +void SimpleFilterModifier::update_filters() +{ + const SPFilter* active_filter = get_selected_filter(); + + FilterEffectChooser::update_filters(); + + if(_model->children().empty()) { + // Set state if no filters exist + Gtk::TreeModel::Row row = *_model->prepend(); + row[_columns.filter] = 0; + row[_columns.id] = "None"; + _filter.set_sensitive(false); + _filter.set_active(0); + } + else { + _filter.set_sensitive(true); + select_filter(active_filter); + } +} + +void SimpleFilterModifier::show_filter_dialog() +{ + SP_ACTIVE_DESKTOP->_dlg_mgr->showDialog("FilterEffectsDialog"); +} + +void SimpleFilterModifier::blend_mode_changed() +{ + if(_blend.get_active_row_number() == 5) { + _vb_blur.hide(); + _hb_filter.show(); + } + else { + _hb_filter.hide(); + _vb_blur.show(); + } +} + +/*** From filter-effect-enums.h ***/ +const EnumData<NR::FilterPrimitiveType> FPData[NR::NR_FILTER_ENDPRIMITIVETYPE] = { + {NR::NR_FILTER_BLEND, _("Blend"), "svg:feBlend"}, + {NR::NR_FILTER_COLORMATRIX, _("Color Matrix"), "svg:feColorMatrix"}, + {NR::NR_FILTER_COMPONENTTRANSFER, _("Component Transfer"), "svg:feComponentTransfer"}, + {NR::NR_FILTER_COMPOSITE, _("Composite"), "svg:feComposite"}, + {NR::NR_FILTER_CONVOLVEMATRIX, _("Convolve Matrix"), "svg:feConvolveMatrix"}, + {NR::NR_FILTER_DIFFUSELIGHTING, _("Diffuse Lighting"), "svg:feDiffuseLighting"}, + {NR::NR_FILTER_DISPLACEMENTMAP, _("Displacement Map"), "svg:feDisplacementMap"}, + {NR::NR_FILTER_FLOOD, _("Flood"), "svg:feFlood"}, + {NR::NR_FILTER_GAUSSIANBLUR, _("Gaussian Blur"), "svg:feGaussianBlur"}, + {NR::NR_FILTER_IMAGE, _("Image"), "svg:feImage"}, + {NR::NR_FILTER_MERGE, _("Merge"), "svg:feMerge"}, + {NR::NR_FILTER_MORPHOLOGY, _("Morphology"), "svg:feMorphology"}, + {NR::NR_FILTER_OFFSET, _("Offset"), "svg:feOffset"}, + {NR::NR_FILTER_SPECULARLIGHTING, _("Specular Lighting"), "svg:feSpecularLighting"}, + {NR::NR_FILTER_TILE, _("Tile"), "svg:feTile"}, + {NR::NR_FILTER_TURBULENCE, _("Turbulence"), "svg:feTurbulence"} +}; +const Converter<NR::FilterPrimitiveType> FPConverter(FPData, NR::NR_FILTER_ENDPRIMITIVETYPE); +const EnumData<NR::FilterBlendMode> BlendModeData[NR::BLEND_ENDMODE] = { + {NR::BLEND_NORMAL, _("Normal"), "normal"}, + {NR::BLEND_MULTIPLY, _("Multiply"), "multiply"}, + {NR::BLEND_SCREEN, _("Screen"), "screen"}, + {NR::BLEND_DARKEN, _("Darken"), "darken"}, + {NR::BLEND_LIGHTEN, _("Lighten"), "lighten"} +}; +const Converter<NR::FilterBlendMode> BlendModeConverter(BlendModeData, NR::BLEND_ENDMODE); + +} +} +} + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/filter-effect-chooser.h b/src/ui/widget/filter-effect-chooser.h new file mode 100644 index 000000000..182ce45ef --- /dev/null +++ b/src/ui/widget/filter-effect-chooser.h @@ -0,0 +1,120 @@ +#ifndef __FILTER_EFFECT_CHOOSER_H__ +#define __FILTER_EFFECT_CHOOSER_H__ + +/* + * Filter effect selection selection widget + * + * Author: + * Nicholas Bishop <nicholasbishop@gmail.com> + * + * Copyright (C) 2007 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include <gtkmm/box.h> +#include <gtkmm/combobox.h> +#include <gtkmm/liststore.h> +#include <gtkmm/treeview.h> + +#include "filter-effect-enums.h" +#include "labelled.h" +#include "spin-slider.h" +#include "sp-filter.h" + +namespace Inkscape { +namespace UI { +namespace Widget { + +class FilterEffectChooser +{ +public: + virtual ~FilterEffectChooser() {} + + virtual Glib::SignalProxy0<void> signal_selection_changed() = 0; + virtual SPFilter* get_selected_filter() = 0; + virtual void select_filter(const SPFilter*) = 0; +protected: + FilterEffectChooser(); + + class Columns : public Gtk::TreeModel::ColumnRecord + { + public: + Columns() + { + add(filter); + add(id); + } + + Gtk::TreeModelColumn<SPFilter*> filter; + Gtk::TreeModelColumn<Glib::ustring> id; + }; + + virtual void update_filters(); + + Glib::RefPtr<Gtk::ListStore> _model; + Columns _columns; +private: + static void on_activate_desktop(Inkscape::Application*, SPDesktop*, FilterEffectChooser*); + void on_document_replaced(SPDesktop*, SPDocument*); + + sigc::connection _doc_replaced; + sigc::connection _resource_changed; + + Gtk::TreeView::Column _filter_column; +}; + +/* Allows basic control over feBlend and feGaussianBlur effects, + with an option to use the full filter effect controls. */ +class SimpleFilterModifier : public Gtk::VBox, public FilterEffectChooser +{ +public: + SimpleFilterModifier(); + + virtual Glib::SignalProxy0<void> signal_selection_changed(); + virtual SPFilter* get_selected_filter(); + virtual void select_filter(const SPFilter*); + + sigc::signal<void>& signal_blend_blur_changed(); + + const Glib::ustring get_blend_mode(); + // Uses blend mode enum values, or -1 for a complex filter + void set_blend_mode(const int); + + double get_blur_value() const; + void set_blur_value(const double); + void set_blur_sensitive(const bool); +protected: + virtual void update_filters(); +private: + void show_filter_dialog(); + void blend_mode_changed(); + + Gtk::HBox _hb_blend; + Gtk::VBox _vb_blur; + Gtk::HBox _hb_filter, _hb_filter_sub; + Gtk::Label _lb_blend, _lb_blur, _lb_filter; + ComboBoxEnum<NR::FilterBlendMode> _blend; + SpinSlider _blur; + Gtk::ComboBox _filter; + Gtk::Button _edit_filters; + + sigc::signal<void> _signal_blend_blur_changed; +}; + +} +} +} + +#endif + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/filter-effect-enums.h b/src/ui/widget/filter-effect-enums.h new file mode 100644 index 000000000..3ac68a16f --- /dev/null +++ b/src/ui/widget/filter-effect-enums.h @@ -0,0 +1,156 @@ +/** + * \brief Simplified management of enumerations for filter effects + * + * Authors: + * Nicholas Bishop <nicholasbishop@gmail.com> + * + * Copyright (C) 2007 Authors + * + * Released under GNU GPL. Read the file 'COPYING' for more information. + */ + +#ifndef INKSCAPE_UI_WIDGET_FILTER_EFFECT_ENUMS_H +#define INKSCAPE_UI_WIDGET_FILTER_EFFECT_ENUMS_H + +#include "display/nr-filter-blend.h" +#include "display/nr-filter-types.h" + +namespace Inkscape { +namespace UI { +namespace Widget { + +template<typename E> struct EnumData +{ + E id; + const Glib::ustring label; + const Glib::ustring name; +}; + +template<typename E> class Converter +{ +public: + typedef EnumData<E> Data; + + Converter(const EnumData<E>* cd, const int endval) + : end(endval), _data(cd) + {} + + E get_id_from_label(const Glib::ustring& label) const + { + for(int i = 0; i < end; ++i) { + if(_data[i].label == label) + return (E)i; + } + + return (E)0; + } + + E get_id_from_name(const Glib::ustring& name) const + { + for(int i = 0; i < end; ++i) { + if(_data[i].name == name) + return (E)i; + } + + return (E)0; + } + + const Glib::ustring& get_label(const E e) const + { + return _data[e].label; + } + + const Glib::ustring& get_name(const E e) const + { + return _data[e].name; + } + + const EnumData<E>& data(const int i) const + { + return _data[i]; + } + + const int end; +private: + const EnumData<E>* _data; +}; + +template<typename E> class ComboBoxEnum : public Gtk::ComboBox +{ +public: + ComboBoxEnum(const Converter<E>& c) + : _converter(c) + { + _model = Gtk::ListStore::create(_columns); + set_model(_model); + + pack_start(_columns.label); + + // Initialize list + for(int i = 0; i < _converter.end; ++i) { + Gtk::TreeModel::Row row = *_model->append(); + const EnumData<E>* data = &_converter.data(i); + row[_columns.data] = data; + row[_columns.label] = _converter.get_label(data->id); + } + + set_active(0); + } + + const EnumData<E>* get_active_data() + { + Gtk::TreeModel::iterator i = this->get_active(); + if(i) + return (*i)[_columns.data]; + return 0; + } + + void add_row(const Glib::ustring& s) + { + Gtk::TreeModel::Row row = *_model->append(); + row[_columns.data] = 0; + row[_columns.label] = s; + } +private: + class Columns : public Gtk::TreeModel::ColumnRecord + { + public: + Columns() + { + add(data); + add(label); + } + + Gtk::TreeModelColumn<const EnumData<E>*> data; + Gtk::TreeModelColumn<Glib::ustring> label; + }; + + Columns _columns; + Glib::RefPtr<Gtk::ListStore> _model; + const Converter<E>& _converter; +}; + +/*** Filter Primitives ***/ +extern const EnumData<NR::FilterPrimitiveType> FPData[NR::NR_FILTER_ENDPRIMITIVETYPE]; +extern const Converter<NR::FilterPrimitiveType> FPConverter; + +/*** feBlend Mode ***/ +extern const EnumData<NR::FilterBlendMode> BlendModeData[NR::BLEND_ENDMODE]; +extern const Converter<NR::FilterBlendMode> BlendModeConverter; + +} +} +} + +#endif + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/spin-slider.cpp b/src/ui/widget/spin-slider.cpp new file mode 100644 index 000000000..678b8e372 --- /dev/null +++ b/src/ui/widget/spin-slider.cpp @@ -0,0 +1,87 @@ +/** + * \brief Groups an HScale and a SpinButton together using the same Adjustment + * + * Author: + * Nicholas Bishop <nicholasbishop@gmail.com> + * + * Copyright (C) 2007 Author + * + * Released under GNU GPL. Read the file 'COPYING' for more information. + */ + +#include "spin-slider.h" + +namespace Inkscape { +namespace UI { +namespace Widget { + + +SpinSlider::SpinSlider(double value, double lower, double upper, double step_inc, + double climb_rate, int digits) + : _adjustment(value, lower, upper, step_inc), + _scale(_adjustment), _spin(_adjustment, climb_rate, digits) +{ + pack_start(_scale); + pack_start(_spin, false, false); + + _scale.set_draw_value(false); + + show_all_children(); +} + +Glib::SignalProxy0<void> SpinSlider::signal_value_changed() +{ + return _adjustment.signal_value_changed(); +} + +double SpinSlider::get_value() const +{ + return _adjustment.get_value(); +} + +void SpinSlider::set_value(const double val) +{ + _adjustment.set_value(val); +} + +const Gtk::Adjustment& SpinSlider::get_adjustment() const +{ + return _adjustment; +} +Gtk::Adjustment& SpinSlider::get_adjustment() +{ + return _adjustment; +} + +const Gtk::HScale& SpinSlider::get_scale() const +{ + return _scale; +} +Gtk::HScale& SpinSlider::get_scale() +{ + return _scale; +} + +const Gtk::SpinButton& SpinSlider::get_spin_button() const +{ + return _spin; +} +Gtk::SpinButton& SpinSlider::get_spin_button() +{ + return _spin; +} + +} // namespace Widget +} // namespace UI +} // namespace Inkscape + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/ui/widget/spin-slider.h b/src/ui/widget/spin-slider.h new file mode 100644 index 000000000..50bd1dc04 --- /dev/null +++ b/src/ui/widget/spin-slider.h @@ -0,0 +1,64 @@ +/** + * \brief Groups an HScale and a SpinButton together using the same Adjustment + * + * Author: + * Nicholas Bishop <nicholasbishop@gmail.com> + * + * Copyright (C) 2007 Author + * + * Released under GNU GPL. Read the file 'COPYING' for more information. + */ + +#ifndef INKSCAPE_UI_WIDGET_SPIN_SLIDER_H +#define INKSCAPE_UI_WIDGET_SPIN_SLIDER_H + +#include <gtkmm/adjustment.h> +#include <gtkmm/box.h> +#include <gtkmm/scale.h> +#include <gtkmm/spinbutton.h> + +namespace Inkscape { +namespace UI { +namespace Widget { + +class SpinSlider : public Gtk::HBox +{ +public: + SpinSlider(double value, double lower, double upper, double step_inc, + double climb_rate, int digits); + + // Shortcuts to _adjustment + Glib::SignalProxy0<void> signal_value_changed(); + double get_value() const; + void set_value(const double); + + const Gtk::Adjustment& get_adjustment() const; + Gtk::Adjustment& get_adjustment(); + + const Gtk::HScale& get_scale() const; + Gtk::HScale& get_scale(); + + const Gtk::SpinButton& get_spin_button() const; + Gtk::SpinButton& get_spin_button(); +private: + Gtk::Adjustment _adjustment; + Gtk::HScale _scale; + Gtk::SpinButton _spin; +}; + +} // namespace Widget +} // namespace UI +} // namespace Inkscape + +#endif // INKSCAPE_UI_WIDGET_SPIN_SLIDER_H + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : |
