X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fui%2Fdialog%2Ffilter-effects-dialog.cpp;h=fbab4a73b4be5869718db788d535983625dab776;hb=d21f06832e860b1f1078c81ce082d450ca5dc3d7;hp=18610f613b6dcb37962d6a6331c14ee6d826a7eb;hpb=9aadd756cef197bd6b06ce8b66a61f35c10bff1a;p=inkscape.git diff --git a/src/ui/dialog/filter-effects-dialog.cpp b/src/ui/dialog/filter-effects-dialog.cpp index 18610f613..fbab4a73b 100644 --- a/src/ui/dialog/filter-effects-dialog.cpp +++ b/src/ui/dialog/filter-effects-dialog.cpp @@ -169,10 +169,12 @@ void FilterEffectsDialog::FilterModifier::remove_filter() void FilterEffectsDialog::FilterModifier::duplicate_filter() { - SPFilter *filter = get_selected_filter(); + SPFilter* filter = get_selected_filter(); if(filter) { - //SPFilter *dupfilter = filter_duplicate(sp_desktop_document(SP_ACTIVE_DESKTOP), filter); + Inkscape::XML::Node* repr = SP_OBJECT_REPR(filter), *parent = repr->parent(); + repr = repr->duplicate(repr->document()); + parent->appendChild(repr); sp_document_done(filter->document, SP_VERB_DIALOG_FILTER_EFFECTS, _("Duplicate filter")); @@ -229,7 +231,7 @@ void FilterEffectsDialog::CellRendererConnection::get_size_vfunc( (*width) = size * primlist.primitive_count(); if(height) { // Scale the height depending on the number of inputs, unless it's - // the first primitive, in which case their are no connections + // the first primitive, in which case there are no connections SPFilterPrimitive* prim = (SPFilterPrimitive*)_primitive.get_value(); (*height) = primlist.is_first(prim) ? size : size * input_count(prim); } @@ -243,8 +245,7 @@ FilterEffectsDialog::PrimitiveList::PrimitiveList(FilterEffectsDialog& d) _model = Gtk::ListStore::create(_columns); - // TODO: reenable this once it is possible to modify the order in the backend - //set_reorderable(true); + set_reorderable(true); set_model(_model); append_column(_("_Type"), _columns.type); @@ -509,6 +510,8 @@ bool FilterEffectsDialog::PrimitiveList::on_button_press_event(GdkEventButton* e Gtk::TreeViewColumn* col; const int x = (int)e->x, y = (int)e->y; int cx, cy; + + _drag_prim = 0; if(get_path_at_pos(x, y, path, col, cx, cy)) { Gtk::TreeIter iter = _model->get_iter(path); @@ -521,9 +524,15 @@ bool FilterEffectsDialog::PrimitiveList::on_button_press_event(GdkEventButton* e queue_draw(); } + _drag_prim = (*iter)[_columns.primitive]; } - return Gtk::TreeView::on_button_press_event(e); + if(_in_drag) { + get_selection()->select(path); + return true; + } + else + return Gtk::TreeView::on_button_press_event(e); } bool FilterEffectsDialog::PrimitiveList::on_motion_notify_event(GdkEventMotion* e) @@ -590,18 +599,65 @@ bool FilterEffectsDialog::PrimitiveList::on_button_release_event(GdkEventButton* return Gtk::TreeView::on_button_release_event(e); } +// Checks all of prim's inputs, removes any that use result +void check_single_connection(SPFilterPrimitive* prim, const int result) +{ + if(prim && result >= 0) { + + if(prim->image_in == result) + SP_OBJECT_REPR(prim)->setAttribute("in", 0); + + if(SP_IS_FEBLEND(prim)) { + if(SP_FEBLEND(prim)->in2 == result) + SP_OBJECT_REPR(prim)->setAttribute("in2", 0); + } + else if(SP_IS_FECOMPOSITE(prim)) { + if(SP_FECOMPOSITE(prim)->in2 == result) + SP_OBJECT_REPR(prim)->setAttribute("in2", 0); + } + } +} + +// Remove any connections going to/from prim_iter that forward-reference other primitives +void FilterEffectsDialog::PrimitiveList::sanitize_connections(const Gtk::TreeIter& prim_iter) +{ + SPFilterPrimitive *prim = (*prim_iter)[_columns.primitive]; + bool before = true; + + for(Gtk::TreeIter iter = _model->children().begin(); + iter != _model->children().end(); ++iter) { + if(iter == prim_iter) + before = false; + else { + SPFilterPrimitive* cur_prim = (*iter)[_columns.primitive]; + if(before) + check_single_connection(cur_prim, prim->image_out); + else + check_single_connection(prim, cur_prim->image_out); + } + } +} + // Reorder the filter primitives to match the list order void FilterEffectsDialog::PrimitiveList::on_drag_end(const Glib::RefPtr&) { SPFilter* filter = _dialog._filter_modifier.get_selected_filter(); + int ndx = 0; for(Gtk::TreeModel::iterator iter = _model->children().begin(); - iter != _model->children().end(); ++iter) { + iter != _model->children().end(); ++iter, ++ndx) { SPFilterPrimitive* prim = (*iter)[_columns.primitive]; - if(prim) - ;//reorder_primitive(filter, prim->repr->position(), ndx); /* FIXME */ + if(prim) { + SP_OBJECT_REPR(prim)->setPosition(ndx); + if(_drag_prim == prim) { + sanitize_connections(iter); + get_selection()->select(iter); + } + } } + filter->requestModified(SP_OBJECT_MODIFIED_FLAG); + sp_document_done(filter->document, SP_VERB_DIALOG_FILTER_EFFECTS, _("Reorder filter primitive")); } @@ -666,6 +722,82 @@ void FilterEffectsDialog::SettingsGroup::add_setting(std::vector& add_setting_generic(*hb, label); } +/*** ConvolveMatrix ***/ +FilterEffectsDialog::ConvolveMatrixColumns::ConvolveMatrixColumns() +{ + cols.resize(5); + for(unsigned i = 0; i < cols.size(); ++i) + add(cols[i]); +} + +FilterEffectsDialog::ConvolveMatrix::ConvolveMatrix() +{ + _model = Gtk::ListStore::create(_columns); + set_model(_model); + set_headers_visible(false); +} + +sigc::signal& FilterEffectsDialog::ConvolveMatrix::signal_changed() +{ + return _signal_changed; +} + +Glib::ustring FilterEffectsDialog::ConvolveMatrix::get_value() const +{ + std::ostringstream os; + + for(Gtk::TreeIter iter = _model->children().begin(); + iter != _model->children().end(); ++iter) { + for(unsigned c = 0; c < get_columns().size(); ++c) { + os << (*iter)[_columns.cols[c]] << " "; + } + } + + return os.str(); +} + +void FilterEffectsDialog::ConvolveMatrix::update(SPFeConvolveMatrix* conv) +{ + if(conv) { + int cols, rows; + + cols = (int)conv->order.getNumber(); + if(cols > 5) + cols = 5; + rows = conv->order.optNumber_set ? (int)conv->order.getOptNumber() : cols; + + update(conv, cols, rows); + } +} + +void FilterEffectsDialog::ConvolveMatrix::update(SPFeConvolveMatrix* conv, const int rows, const int cols) +{ + _model->clear(); + + remove_all_columns(); + + if(conv) { + int ndx = 0; + + for(int i = 0; i < cols; ++i) { + append_column_numeric_editable("", _columns.cols[i], "%.2f"); + dynamic_cast(get_column(i)->get_first_cell_renderer())->signal_edited().connect( + sigc::mem_fun(*this, &ConvolveMatrix::rebind)); + } + + for(int r = 0; r < rows; ++r) { + Gtk::TreeRow row = *(_model->append()); + for(int c = 0; c < cols; ++c, ++ndx) + row[_columns.cols[c]] = ndx < (int)conv->kernelMatrix.size() ? conv->kernelMatrix[ndx] : 0; + } + } +} + +void FilterEffectsDialog::ConvolveMatrix::rebind(const Glib::ustring&, const Glib::ustring&) +{ + _signal_changed(); +} + /*** FilterEffectsDialog ***/ FilterEffectsDialog::FilterEffectsDialog() @@ -685,6 +817,10 @@ FilterEffectsDialog::FilterEffectsDialog() _composite_k2(0, -10, 10, 1, 0.01, 1), _composite_k3(0, -10, 10, 1, 0.01, 1), _composite_k4(0, -10, 10, 1, 0.01, 1), + _convolve_orderx(1, 0), + _convolve_ordery(1, 0), + _convolve_divisor(1, 0.01, 10, 1, 0.01, 1), + _convolve_bias(0, -10, 10, 1, 0.01, 1), _gaussianblur_stddeviation(1, 0, 100, 1, 0.01, 1), _morphology_radius(1, 0, 100, 1, 0.01, 1), _offset_dx(0, -100, 100, 1, 0.01, 1), @@ -768,6 +904,25 @@ void FilterEffectsDialog::init_settings_widgets() _composite.add_setting(_composite_k4, SP_ATTR_K4, _("K4")); _convolvematrix.init(this, _settings_labels); + _convolvematrix.add_setting_generic(_convolve_orderx, _("Rows")); + _convolve_orderx.set_range(1, 5); + _convolve_orderx.get_adjustment()->set_step_increment(1); + _convolve_orderx.signal_value_changed().connect( + sigc::bind(sigc::mem_fun(*this, &FilterEffectsDialog::set_attr_special), SP_ATTR_ORDER)); + _convolvematrix.add_setting_generic(_convolve_ordery, _("Columns")); + _convolve_ordery.set_range(1, 5); + _convolve_ordery.get_adjustment()->set_step_increment(1); + _convolve_ordery.signal_value_changed().connect( + sigc::bind(sigc::mem_fun(*this, &FilterEffectsDialog::set_attr_special), SP_ATTR_ORDER)); + Gtk::ScrolledWindow* sw = Gtk::manage(new Gtk::ScrolledWindow); + sw->add(_convolve_kernelmatrix); + sw->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); + sw->set_shadow_type(Gtk::SHADOW_IN); + _convolvematrix.add_setting_generic(*sw, _("Kernel")); + _convolve_kernelmatrix.signal_changed().connect( + sigc::bind(sigc::mem_fun(*this, &FilterEffectsDialog::set_attr_special), SP_ATTR_KERNELMATRIX)); + //_convolvematrix.add_setting(_convolve_divisor, SP_ATTR_DIVISOR, _("Divisor")); + //_convolvematrix.add_setting(_convolve_bias, SP_ATTR_BIAS, _("Bias")); _diffuselighting.init(this, _settings_labels); @@ -862,6 +1017,7 @@ void FilterEffectsDialog::set_attr_special(const SPAttributeEnum attr) { Glib::ustring val; FilterPrimitiveInput input_id; + std::ostringstream os; switch(attr) { case SP_ATTR_IN: @@ -881,6 +1037,18 @@ void FilterEffectsDialog::set_attr_special(const SPAttributeEnum attr) val = FPInputConverter.get_key(input_id); } break; + case SP_ATTR_ORDER: + { + int x = (int)(_convolve_orderx.get_value() + 0.5f); + int y = (int)(_convolve_ordery.get_value() + 0.5f); + os << x << " " << y; + val = os.str(); + _convolve_kernelmatrix.update(SP_FECONVOLVEMATRIX(_primitive_list.get_selected()), x, y); + break; + } + case SP_ATTR_KERNELMATRIX: + val = _convolve_kernelmatrix.get_value(); + break; default: return; } @@ -953,8 +1121,13 @@ void FilterEffectsDialog::update_settings_view() _composite_k3.set_value(comp->k3); _composite_k4.set_value(comp->k4); } - else if(tid == NR::NR_FILTER_CONVOLVEMATRIX) + else if(tid == NR::NR_FILTER_CONVOLVEMATRIX) { _convolvematrix.show_all(); + SPFeConvolveMatrix* conv = SP_FECONVOLVEMATRIX(prim); + _convolve_orderx.set_value(conv->order.getNumber()); + _convolve_ordery.set_value(conv->order.optNumber_set ? conv->order.getOptNumber() : conv->order.getNumber()); + _convolve_kernelmatrix.update(conv); + } else if(tid == NR::NR_FILTER_DIFFUSELIGHTING) _diffuselighting.show_all(); else if(tid == NR::NR_FILTER_DISPLACEMENTMAP) {