Code

Filter effects dialog:
authornicholasbishop <nicholasbishop@users.sourceforge.net>
Tue, 17 Jul 2007 07:22:28 +0000 (07:22 +0000)
committernicholasbishop <nicholasbishop@users.sourceforge.net>
Tue, 17 Jul 2007 07:22:28 +0000 (07:22 +0000)
* Enables drag-and-drop reordering for filter primitives. Removes any connection conflicts caused by reordering.

src/ui/dialog/filter-effects-dialog.cpp
src/ui/dialog/filter-effects-dialog.h

index 18610f613b6dcb37962d6a6331c14ee6d826a7eb..cb0a52db283ceaf93c1b3b54922d691309468f65 100644 (file)
@@ -229,7 +229,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 +243,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 +508,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 +522,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 +597,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<Gdk::DragContext>&)
 {
     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"));
 }
 
index 9d4c54fe0f16048669d39d40e4feca035f8fc7d3..b98d47d1a761ef80a721184aa3b980eaca49f764 100644 (file)
@@ -124,12 +124,14 @@ private:
         const Gtk::TreeIter find_result(const Gtk::TreeIter& start, const SPAttributeEnum attr);
         int find_index(const Gtk::TreeIter& target);
         void draw_connection(const Gtk::TreeIter&, const int x1, const int y1, const int row_count);
+        void sanitize_connections(const Gtk::TreeIter& prim_iter);
 
         FilterEffectsDialog& _dialog;
         Glib::RefPtr<Gtk::ListStore> _model;
         PrimitiveColumns _columns;
         Glib::RefPtr<Gtk::Menu> _primitive_menu;
         int _in_drag;
+        SPFilterPrimitive* _drag_prim;
     };
 
     class SettingsGroup : public Gtk::VBox