From 77e0947f5d14388f467e663e9f84e933ccfc0b80 Mon Sep 17 00:00:00 2001 From: nicholasbishop Date: Wed, 8 Aug 2007 05:37:45 +0000 Subject: [PATCH] Filter effects dialog: * Connected up the filters and primitives so that changes made outside the filter dialog are properly observed, e.g. deleting a primitive in the XML editor will show up in the filter dialog. --- src/ui/dialog/filter-effects-dialog.cpp | 106 +++++++++++++++++++----- src/ui/dialog/filter-effects-dialog.h | 12 ++- src/ui/widget/filter-effect-chooser.h | 3 +- 3 files changed, 98 insertions(+), 23 deletions(-) diff --git a/src/ui/dialog/filter-effects-dialog.cpp b/src/ui/dialog/filter-effects-dialog.cpp index 116d0ec89..903701cf5 100644 --- a/src/ui/dialog/filter-effects-dialog.cpp +++ b/src/ui/dialog/filter-effects-dialog.cpp @@ -52,6 +52,7 @@ #include "svg/svg-color.h" #include "verbs.h" #include "xml/node.h" +#include "xml/node-observer.h" #include "xml/repr.h" #include @@ -80,6 +81,48 @@ int input_count(const SPFilterPrimitive* prim) return 1; } +// Very simple observer that just emits a signal if anything happens to a node +class FilterEffectsDialog::SignalObserver : public XML::NodeObserver +{ +public: + SignalObserver() + : _oldsel(0) + {} + + // Add this observer to the SPObject and remove it from any previous object + void set(SPObject* o) + { + if(_oldsel && _oldsel->repr) + _oldsel->repr->removeObserver(*this); + if(o && o->repr) + o->repr->addObserver(*this); + _oldsel = o; + } + + void notifyChildAdded(XML::Node&, XML::Node&, XML::Node*) + { signal_changed()(); } + + void notifyChildRemoved(XML::Node&, XML::Node&, XML::Node*) + { signal_changed()(); } + + void notifyChildOrderChanged(XML::Node&, XML::Node&, XML::Node*, XML::Node*) + { signal_changed()(); } + + void notifyContentChanged(XML::Node&, Util::ptr_shared, Util::ptr_shared) + {} + + void notifyAttributeChanged(XML::Node&, GQuark, Util::ptr_shared, Util::ptr_shared) + { signal_changed()(); } + + sigc::signal& signal_changed() + { + return _signal_changed; + } +private: + sigc::signal _signal_changed; + SPObject* _oldsel; +}; + class CheckButtonAttr : public Gtk::CheckButton, public AttrWidget { public: @@ -437,7 +480,7 @@ public: typedef sigc::slot SetAttrSlot; Settings(FilterEffectsDialog& d, SetAttrSlot slot, const int maxtypes) - : _dialog(d), _set_attr_slot(slot), _max_types(maxtypes) + : _dialog(d), _set_attr_slot(slot), _current_type(-1), _max_types(maxtypes) { _groups.resize(_max_types); _attrwidgets.resize(_max_types); @@ -460,9 +503,11 @@ public: // Show the active settings group and update all the AttrWidgets with new values void show_and_update(const int t, SPObject* ob) { - type(t); - for(unsigned i = 0; i < _groups.size(); ++i) - _groups[i]->hide(); + if(t != _current_type) { + type(t); + for(unsigned i = 0; i < _groups.size(); ++i) + _groups[i]->hide(); + } _groups[t]->show_all(); _dialog.set_attrs_locked(true); @@ -471,6 +516,11 @@ public: _dialog.set_attrs_locked(false); } + int get_current_type() const + { + return _current_type; + } + void type(const int t) { _current_type = t; @@ -741,7 +791,7 @@ Glib::RefPtr create_popup_menu(Gtk::Widget& parent, sigc::slot /*** FilterModifier ***/ FilterEffectsDialog::FilterModifier::FilterModifier(FilterEffectsDialog& d) - : _dialog(d), _add(Gtk::Stock::ADD) + : _dialog(d), _add(Gtk::Stock::ADD), _observer(new SignalObserver) { Gtk::ScrolledWindow* sw = Gtk::manage(new Gtk::ScrolledWindow); pack_start(*sw); @@ -769,6 +819,8 @@ FilterEffectsDialog::FilterModifier::FilterModifier(FilterEffectsDialog& d) _("R_ename"), sigc::mem_fun(*this, &FilterModifier::rename_filter))); _menu->accelerate(*this); + _list.get_selection()->signal_changed().connect(sigc::mem_fun(*this, &FilterModifier::on_filter_selection_changed)); + _observer->signal_changed().connect(signal_filter_changed().make_slot()); g_signal_connect(G_OBJECT(INKSCAPE), "change_selection", G_CALLBACK(&FilterModifier::on_inkscape_change_selection), this); @@ -855,9 +907,15 @@ void FilterEffectsDialog::FilterModifier::update_selection(Selection *sel) } } -Glib::SignalProxy0 FilterEffectsDialog::FilterModifier::signal_selection_changed() +void FilterEffectsDialog::FilterModifier::on_filter_selection_changed() { - return _list.get_selection()->signal_changed(); + _observer->set(get_selected_filter()); + signal_filter_changed()(); +} + +sigc::signal& FilterEffectsDialog::FilterModifier::signal_filter_changed() +{ + return _signal_filter_changed; } SPFilter* FilterEffectsDialog::FilterModifier::get_selected_filter() @@ -1035,7 +1093,8 @@ void FilterEffectsDialog::CellRendererConnection::get_size_vfunc( /*** PrimitiveList ***/ FilterEffectsDialog::PrimitiveList::PrimitiveList(FilterEffectsDialog& d) : _dialog(d), - _in_drag(0) + _in_drag(0), + _observer(new SignalObserver) { add_events(Gdk::POINTER_MOTION_MASK | Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK); signal_expose_event().connect(sigc::mem_fun(*this, &PrimitiveList::on_expose_signal)); @@ -1047,7 +1106,9 @@ FilterEffectsDialog::PrimitiveList::PrimitiveList(FilterEffectsDialog& d) set_model(_model); append_column(_("_Type"), _columns.type); - signal_selection_changed().connect(sigc::mem_fun(*this, &PrimitiveList::queue_draw)); + _observer->signal_changed().connect(signal_primitive_changed().make_slot()); + get_selection()->signal_changed().connect(sigc::mem_fun(*this, &PrimitiveList::on_primitive_selection_changed)); + signal_primitive_changed().connect(sigc::mem_fun(*this, &PrimitiveList::queue_draw)); _connection_cell.set_text_width(init_text()); @@ -1079,9 +1140,15 @@ int FilterEffectsDialog::PrimitiveList::init_text() return maxfont; } -Glib::SignalProxy0 FilterEffectsDialog::PrimitiveList::signal_selection_changed() +sigc::signal& FilterEffectsDialog::PrimitiveList::signal_primitive_changed() +{ + return _signal_primitive_changed; +} + +void FilterEffectsDialog::PrimitiveList::on_primitive_selection_changed() { - return get_selection()->signal_changed(); + _observer->set(get_selected()); + signal_primitive_changed()(); } /* Add all filter primitives in the current to the list. @@ -1610,9 +1677,9 @@ FilterEffectsDialog::FilterEffectsDialog() fr_settings->add(*al_settings); al_settings->add(_settings_box); - _primitive_list.signal_selection_changed().connect( + _primitive_list.signal_primitive_changed().connect( sigc::mem_fun(*this, &FilterEffectsDialog::update_settings_view)); - _filter_modifier.signal_selection_changed().connect( + _filter_modifier.signal_filter_changed().connect( sigc::mem_fun(_primitive_list, &PrimitiveList::update)); sw_prims->set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC); @@ -1790,14 +1857,15 @@ void FilterEffectsDialog::update_settings_view() { SPFilterPrimitive* prim = _primitive_list.get_selected(); - // Hide all the settings - _settings_box.hide_all(); - _settings_box.show(); - - if(prim) + if(prim) { _settings->show_and_update(FPConverter.get_id_from_key(prim->repr->name()), prim); - else + _empty_settings.hide(); + } + else { + _settings_box.hide_all(); + _settings_box.show(); _empty_settings.show(); + } update_settings_sensitivity(); } diff --git a/src/ui/dialog/filter-effects-dialog.h b/src/ui/dialog/filter-effects-dialog.h index 96fb481a0..4fdd6f957 100644 --- a/src/ui/dialog/filter-effects-dialog.h +++ b/src/ui/dialog/filter-effects-dialog.h @@ -46,6 +46,8 @@ public: static FilterEffectsDialog *create() { return new FilterEffectsDialog(); } private: + class SignalObserver; + class FilterModifier : public Gtk::VBox, public FilterEffectChooser { public: @@ -53,7 +55,7 @@ private: virtual SPFilter* get_selected_filter(); virtual void select_filter(const SPFilter*); - virtual Glib::SignalProxy0 signal_selection_changed(); + sigc::signal& signal_filter_changed(); private: class CellRendererSel : public Gtk::CellRenderer { @@ -73,6 +75,7 @@ private: static void on_inkscape_change_selection(Application *, Selection *, FilterModifier*); void update_selection(Selection *); + void on_filter_selection_changed(); void filter_list_button_press(GdkEventButton*); void filter_list_button_release(GdkEventButton*); @@ -86,6 +89,8 @@ private: CellRendererSel _cell_sel; Gtk::Button _add; Glib::RefPtr _menu; + sigc::signal _signal_filter_changed; + std::auto_ptr _observer; }; class PrimitiveColumns : public Gtk::TreeModel::ColumnRecord @@ -129,7 +134,7 @@ private: public: PrimitiveList(FilterEffectsDialog&); - Glib::SignalProxy0 signal_selection_changed(); + sigc::signal& signal_primitive_changed(); void update(); void set_menu(Glib::RefPtr); @@ -154,6 +159,7 @@ private: void draw_connection(const Gtk::TreeIter&, const int attr, const int text_start_x, const int x1, const int y1, const int row_count); void sanitize_connections(const Gtk::TreeIter& prim_iter); + void on_primitive_selection_changed(); FilterEffectsDialog& _dialog; Glib::RefPtr _model; @@ -163,6 +169,8 @@ private: Glib::RefPtr _vertical_layout; int _in_drag; SPFilterPrimitive* _drag_prim; + sigc::signal _signal_primitive_changed; + std::auto_ptr _observer; }; FilterEffectsDialog(); diff --git a/src/ui/widget/filter-effect-chooser.h b/src/ui/widget/filter-effect-chooser.h index 5d1d16efd..6733fb784 100644 --- a/src/ui/widget/filter-effect-chooser.h +++ b/src/ui/widget/filter-effect-chooser.h @@ -32,7 +32,6 @@ class FilterEffectChooser public: virtual ~FilterEffectChooser(); - virtual Glib::SignalProxy0 signal_selection_changed() = 0; virtual SPFilter* get_selected_filter() = 0; virtual void select_filter(const SPFilter*) = 0; protected: @@ -74,7 +73,7 @@ class SimpleFilterModifier : public Gtk::VBox, public FilterEffectChooser public: SimpleFilterModifier(); - virtual Glib::SignalProxy0 signal_selection_changed(); + Glib::SignalProxy0 signal_selection_changed(); virtual SPFilter* get_selected_filter(); virtual void select_filter(const SPFilter*); -- 2.30.2