Code

New grids are almost ready to fly!
authorjohanengelen <johanengelen@users.sourceforge.net>
Fri, 13 Apr 2007 14:41:49 +0000 (14:41 +0000)
committerjohanengelen <johanengelen@users.sourceforge.net>
Fri, 13 Apr 2007 14:41:49 +0000 (14:41 +0000)
src/desktop-handles.cpp
src/desktop-handles.h
src/desktop.cpp
src/desktop.h
src/display/canvas-axonomgrid.cpp
src/display/canvas-axonomgrid.h
src/display/canvas-grid.cpp
src/display/canvas-grid.h
src/sp-namedview.cpp
src/ui/dialog/document-properties.cpp

index e2d36bb529befb9240f9b7c0b3b0e4080245f604..1241bfa02c7a19bf87c68d96ca52d226c924c527 100644 (file)
@@ -64,11 +64,11 @@ sp_desktop_main (SPDesktop const * desktop)
 }
 
 SPCanvasGroup *
-sp_desktop_grid (SPDesktop const * desktop)
+sp_desktop_gridgroup (SPDesktop const * desktop)
 {
        g_return_val_if_fail (desktop != NULL, NULL);
 
-       return desktop->grid;
+       return desktop->gridgroup;
 }
 
 SPCanvasGroup *
index 3633ef1f00f4eb36aab64f476aff73e6d68400f6..6001ba126e7345bd95e212eeefa8d85e1703fb0a 100644 (file)
@@ -35,7 +35,7 @@ SPDocument * sp_desktop_document (SPDesktop const * desktop);
 SPCanvas * sp_desktop_canvas (SPDesktop const * desktop);
 SPCanvasItem * sp_desktop_acetate (SPDesktop const * desktop);
 SPCanvasGroup * sp_desktop_main (SPDesktop const * desktop);
-SPCanvasGroup * sp_desktop_grid (SPDesktop const * desktop);
+SPCanvasGroup * sp_desktop_gridgroup (SPDesktop const * desktop);
 SPCanvasGroup * sp_desktop_guides (SPDesktop const * desktop);
 SPCanvasItem *sp_desktop_drawing (SPDesktop const *desktop);
 SPCanvasGroup * sp_desktop_sketch (SPDesktop const * desktop);
index 15d5bc9e3423bd8276bcc7e10ebc727eca68273b..561ab1cf04e6bfc7b08457d2e6ceb024617fa152 100644 (file)
@@ -85,6 +85,8 @@
 #include "event-log.h"
 #include "display/canvas-grid.h"
 
+#include "sp-canvas.h"
+
 namespace Inkscape { namespace XML { class Node; }}
 
 // Callback declarations
@@ -111,7 +113,7 @@ SPDesktop::SPDesktop()
     selection = NULL;
     acetate = NULL;
     main = NULL;
-    grid = NULL;
+    gridgroup = NULL;
     guides = NULL;
     drawing = NULL;
     sketch = NULL;
@@ -201,7 +203,7 @@ SPDesktop::init (SPNamedView *nv, SPCanvas *aCanvas)
         setDisplayModeNormal();
     }
 
-    grid = (SPCanvasGroup *) sp_canvas_item_new (main, SP_TYPE_CANVAS_GROUP, NULL);
+    gridgroup = (SPCanvasGroup *) sp_canvas_item_new (main, SP_TYPE_CANVAS_GROUP, NULL);
     guides = (SPCanvasGroup *) sp_canvas_item_new (main, SP_TYPE_CANVAS_GROUP, NULL);
     sketch = (SPCanvasGroup *) sp_canvas_item_new (main, SP_TYPE_CANVAS_GROUP, NULL);
     controls = (SPCanvasGroup *) sp_canvas_item_new (main, SP_TYPE_CANVAS_GROUP, NULL);
@@ -298,6 +300,8 @@ SPDesktop::init (SPNamedView *nv, SPCanvas *aCanvas)
     /* setup LayerManager */
     //   (Setting up after the connections are all in place, as it may use some of them)
     layer_manager = new Inkscape::LayerManager( this );
+    
+    grids_visible = false;
 }
 
 
@@ -1101,9 +1105,13 @@ void SPDesktop::clearWaitingCursor()
 
 void SPDesktop::toggleGrid()
 {
-    for ( GSList const *l = namedview->grids; l != NULL; l = l->next) {
-        Inkscape::CanvasGrid *grid = (Inkscape::CanvasGrid*) l->data;
-        grid->toggle_visibility();
+    if(gridgroup) {
+        grids_visible = !grids_visible;
+        if (grids_visible) {
+            sp_canvas_item_show(SP_CANVAS_ITEM(gridgroup));
+        } else {
+            sp_canvas_item_hide(SP_CANVAS_ITEM(gridgroup));
+        }
     }
 }
 
index 797e74a331677080c5f84e405e7dae7d9a27a8b5..1aae2ebb6bce1421f0b909d4c38104ad5a84edcb 100644 (file)
@@ -85,7 +85,7 @@ struct SPDesktop : public Inkscape::UI::View::View
 
     SPCanvasItem  *acetate;
     SPCanvasGroup *main;
-    SPCanvasGroup *grid;
+    SPCanvasGroup *gridgroup;
     SPCanvasGroup *guides;
     SPCanvasItem  *drawing;
     SPCanvasGroup *sketch;
@@ -249,6 +249,7 @@ struct SPDesktop : public Inkscape::UI::View::View
     void clearWaitingCursor();
     
     void toggleGrid();
+    bool gridsEnabled() { return grids_visible; }
     
     void fullscreen();
 
@@ -276,6 +277,8 @@ private:
     NR::Matrix _d2w;
     NR::Matrix _doc2dt;
     
+    bool grids_visible;
+    
     void push_current_zoom (GList**);
 
     sigc::signal<void,SPDesktop*,SPDocument*>     _document_replaced_signal;
index d384fb5d428beb3ba344a6ca991a26a8be8fd8fc..311c56f4497fa331d8c73ae34977e36b03875857 100644 (file)
@@ -195,8 +195,8 @@ attach_all (Gtk::Table &table, const Gtk::Widget *arr[], unsigned size, int star
     }
 }
 
-CanvasAxonomGrid::CanvasAxonomGrid (SPDesktop *desktop, Inkscape::XML::Node * in_repr)
-    : CanvasGrid(desktop, in_repr), table(1, 1)
+CanvasAxonomGrid::CanvasAxonomGrid (SPNamedView * nv, Inkscape::XML::Node * in_repr)
+    : CanvasGrid(nv, in_repr), table(1, 1)
 {
 
     origin[NR::X] = origin[NR::Y] = 0.0;
@@ -396,8 +396,9 @@ CanvasAxonomGrid::readRepr()
         empspacing = atoi(value);
     }
 
-    sp_canvas_item_request_update (canvasitem);
-
+    for (GSList *l = canvasitems; l != NULL; l = l->next) {
+        sp_canvas_item_request_update ( SP_CANVAS_ITEM(l->data) );
+    }
     return;
 }
 
index d560dad7c9ca49dabf79a5a54a8e99215dffa1c1..0eaf914de01f41d981275c73178aac69bee76c2e 100644 (file)
@@ -33,7 +33,7 @@ namespace Inkscape {
 
 class CanvasAxonomGrid : public CanvasGrid {
 public:
-    CanvasAxonomGrid(SPDesktop *desktop, Inkscape::XML::Node * in_repr);
+    CanvasAxonomGrid(SPNamedView * nv, Inkscape::XML::Node * in_repr);
     ~CanvasAxonomGrid();
 
     void Update (NR::Matrix const &affine, unsigned int flags);
index f343077c3550c3e5aed36afc4f10ead5a5a80842..6644092dffb3298d2f6e034b016655652999aa7f 100644 (file)
@@ -135,25 +135,18 @@ grid_canvasitem_update (SPCanvasItem *item, NR::Matrix const &affine, unsigned i
         NULL  /* order_changed */
     };
 
-CanvasGrid::CanvasGrid(SPDesktop *desktop, Inkscape::XML::Node * in_repr)
+CanvasGrid::CanvasGrid(SPNamedView * nv, Inkscape::XML::Node * in_repr)
 {
-    //create canvasitem
-    // FIXME: probably this creation has to be done on demand. I think for multiple desktops it is best if each has their own canvasitem, but share the same CanvasGrid object.
-    canvasitem = INKSCAPE_GRID_CANVASITEM( sp_canvas_item_new(sp_desktop_grid(desktop), INKSCAPE_TYPE_GRID_CANVASITEM, NULL) );
-    gtk_object_ref(GTK_OBJECT(canvasitem));    // since we're keeping a copy, we need to bump up the ref count
-    canvasitem->grid = this;
-
-    snapenabled = false;
-    visible = false;
-
-//    sp_canvas_item_hide(canvasitem);
+    snapenabled = true;
+    visible = true;
 
     repr = in_repr;
     if (repr) {
         repr->addListener (&_repr_events, this);
     }
-    
-    namedview = sp_desktop_namedview(desktop);
+
+    namedview = nv;
+    canvasitems = NULL;
 }
 
 CanvasGrid::~CanvasGrid()
@@ -162,28 +155,28 @@ CanvasGrid::~CanvasGrid()
         repr->removeListenerByData (this);
     }
 
-    sp_canvas_item_hide(canvasitem);
-   // deref canvasitem
-   gtk_object_unref(GTK_OBJECT(canvasitem));
-   g_free(canvasitem);
+    while (canvasitems) {
+        gtk_object_destroy(GTK_OBJECT(canvasitems->data));
+        canvasitems = g_slist_remove(canvasitems, canvasitems->data);
+    }
 }
 
 /*
-*  writes an <inkscape:grid> child to repr. 
+*  writes an <inkscape:grid> child to repr.
 */
-void 
+void
 CanvasGrid::writeNewGridToRepr(Inkscape::XML::Node * repr, const char * gridtype)
 {
     if (!repr) return;
     if (!gridtype) return;
-    
+
     // first create the child xml node, then hook it to repr. This order is important, to not set off listeners to repr before the new node is complete.
-    
+
     Inkscape::XML::Document *xml_doc = sp_document_repr_doc(sp_desktop_document(SP_ACTIVE_DESKTOP));
     Inkscape::XML::Node *newnode;
     newnode = xml_doc->createElement("inkscape:grid");
     newnode->setAttribute("type",gridtype);
-    
+
     repr->appendChild(newnode);
 
     // FIXME: add this to history?
@@ -192,29 +185,61 @@ CanvasGrid::writeNewGridToRepr(Inkscape::XML::Node * repr, const char * gridtype
 }
 
 /*
-* Creates a new CanvasGrid object of type gridtype 
+* Creates a new CanvasGrid object of type gridtype
 */
-CanvasGrid* 
-CanvasGrid::NewGrid(SPDesktop *desktop, Inkscape::XML::Node * in_repr, const char * gridtype)
+CanvasGrid*
+CanvasGrid::NewGrid(SPNamedView * nv, Inkscape::XML::Node * in_repr, const char * gridtype)
 {
-    if (!desktop) return NULL;
     if (!in_repr) return NULL;
     if (!gridtype) return NULL;
-    
+
     if (!strcmp(gridtype,"xygrid")) {
-        return (CanvasGrid*) new CanvasXYGrid(desktop, in_repr);
+        return (CanvasGrid*) new CanvasXYGrid(nv, in_repr);
     } else if (!strcmp(gridtype,"axonometric")) {
-        return (CanvasGrid*) new CanvasAxonomGrid(desktop, in_repr);
+        return (CanvasGrid*) new CanvasAxonomGrid(nv, in_repr);
     }
-    
+
     return NULL;
 }
 
 
+/**
+*  creates a new grid canvasitem for the SPDesktop given as parameter. Keeps a link to this canvasitem in the canvasitems list.
+*/
+GridCanvasItem *
+CanvasGrid::createCanvasItem(SPDesktop * desktop)
+{
+    if (!desktop) return NULL;
+    //Johan: I think for multiple desktops it is best if each has their own canvasitem, but share the same CanvasGrid object; that is what this function is for.
+
+    // check if there is already a canvasitem on this desktop linking to this grid
+    for (GSList *l = canvasitems; l != NULL; l = l->next) {
+        if ( sp_desktop_gridgroup(desktop) == SP_CANVAS_GROUP(SP_CANVAS_ITEM(l->data)->parent) ) {
+            return NULL;
+        }
+    }
+
+    GridCanvasItem * item = INKSCAPE_GRID_CANVASITEM( sp_canvas_item_new(sp_desktop_gridgroup(desktop), INKSCAPE_TYPE_GRID_CANVASITEM, NULL) );
+    item->grid = this;
+    if (desktop->gridsEnabled()) {
+        sp_canvas_item_show(SP_CANVAS_ITEM(item));
+    } else {
+        sp_canvas_item_hide(SP_CANVAS_ITEM(item));
+    }
+
+    gtk_object_ref(GTK_OBJECT(item));    // since we're keeping a link to this item, we need to bump up the ref count
+    canvasitems = g_slist_prepend(canvasitems, item);
+
+    return item;
+}
+
+
 void
 CanvasGrid::hide()
 {
-    sp_canvas_item_hide(canvasitem);
+    for (GSList *l = canvasitems; l != NULL; l = l->next) {
+        sp_canvas_item_hide ( SP_CANVAS_ITEM(l->data) );
+    }
     visible = false;
     disable_snapping(); // temporary hack, because at the moment visibilty and snapping are linked
 }
@@ -222,12 +247,14 @@ CanvasGrid::hide()
 void
 CanvasGrid::show()
 {
-    sp_canvas_item_show(canvasitem);
+    for (GSList *l = canvasitems; l != NULL; l = l->next) {
+        sp_canvas_item_show ( SP_CANVAS_ITEM(l->data) );
+    }
     visible = true;
     enable_snapping(); // temporary hack, because at the moment visibilty and snapping are linked
 }
 
-void 
+void
 CanvasGrid::set_visibility(bool visible)
 {
     this->visible = visible;
@@ -310,8 +337,8 @@ attach_all (Gtk::Table &table, const Gtk::Widget *arr[], unsigned size, int star
     }
 }
 
-CanvasXYGrid::CanvasXYGrid (SPDesktop *desktop, Inkscape::XML::Node * in_repr)
-    : CanvasGrid(desktop, in_repr), table(1, 1)
+CanvasXYGrid::CanvasXYGrid (SPNamedView * nv, Inkscape::XML::Node * in_repr)
+    : CanvasGrid(nv, in_repr), table(1, 1)
 {
     origin[NR::X] = origin[NR::Y] = 0.0;
 //            nv->gridcolor = (nv->gridcolor & 0xff) | (DEFAULTGRIDCOLOR & 0xffffff00);
@@ -322,9 +349,9 @@ CanvasXYGrid::CanvasXYGrid (SPDesktop *desktop, Inkscape::XML::Node * in_repr)
     empspacing = 5;
     spacing[NR::X] = spacing[NR::Y] = 8.0;
     gridunit = &sp_unit_get_by_id(SP_UNIT_PX);
-    
+
     snapper = new CanvasXYGridSnapper(this, namedview, 0);
-    
+
     // initialize widgets:
     vbox.set_border_width(2);
     table.set_spacings(2);
@@ -487,7 +514,9 @@ CanvasXYGrid::readRepr()
         empspacing = atoi(value);
     }
 
-    sp_canvas_item_request_update (canvasitem);
+    for (GSList *l = canvasitems; l != NULL; l = l->next) {
+        sp_canvas_item_request_update ( SP_CANVAS_ITEM(l->data) );
+    }
 
     return;
 }
@@ -546,7 +575,7 @@ CanvasXYGrid::updateWidgets()
     _rsi.setValue (empspacing);
 
     _wr.setUpdating (false);
-    
+
     return;
 }
 
@@ -640,7 +669,7 @@ CanvasXYGridSnapper::CanvasXYGridSnapper(CanvasXYGrid *grid, SPNamedView const *
     this->grid = grid;
 }
 
-LineSnapper::LineList 
+LineSnapper::LineList
 CanvasXYGridSnapper::_getSnapLines(NR::Point const &p) const
 {
     LineList s;
index 54a57d3d0dc2130dd0ec298613df3df9213dd682..db0f29f40cec4ca46df0d47d82b69f34f9270cc4 100644 (file)
@@ -59,11 +59,13 @@ GtkType grid_canvasitem_get_type (void);
 
 class CanvasGrid {
 public:
-    CanvasGrid(SPDesktop *desktop, Inkscape::XML::Node * in_repr);
+    CanvasGrid(SPNamedView * nv, Inkscape::XML::Node * in_repr);
     virtual ~CanvasGrid();
     
-    static CanvasGrid* NewGrid(SPDesktop *desktop, Inkscape::XML::Node * in_repr, const char * gridtype);
+    static CanvasGrid* NewGrid(SPNamedView * nv, Inkscape::XML::Node * in_repr, const char * gridtype);
     static void writeNewGridToRepr(Inkscape::XML::Node * repr, const char * gridtype);
+
+    GridCanvasItem * createCanvasItem(SPDesktop * desktop);
     
     virtual void Update (NR::Matrix const &affine, unsigned int flags) = 0;
     virtual void Render (SPCanvasBuf *buf) = 0;
@@ -86,8 +88,9 @@ public:
     Inkscape::Snapper* snapper;
 
     static void on_repr_attr_changed (Inkscape::XML::Node * repr, const gchar *key, const gchar *oldval, const gchar *newval, bool is_interactive, void * data);
+    
 protected:
-    GridCanvasItem * canvasitem;
+    GSList * canvasitems;  // list of created canvasitems
 
     SPNamedView * namedview;
     
@@ -105,7 +108,7 @@ private:
 
 class CanvasXYGrid : public CanvasGrid {
 public:
-    CanvasXYGrid(SPDesktop *desktop, Inkscape::XML::Node * in_repr);
+    CanvasXYGrid(SPNamedView * nv, Inkscape::XML::Node * in_repr);
     ~CanvasXYGrid();
 
     void Update (NR::Matrix const &affine, unsigned int flags);
index e5cfa79241a63f5689de2a71abf5cc3fd04fac87..c62c6b62e0c829deceda348526c38d6555bd11eb 100644 (file)
@@ -526,6 +526,48 @@ static void sp_namedview_set(SPObject *object, unsigned int key, const gchar *va
     }
 }
 
+/**
+* add a grid item from SVG-repr. Check if this namedview already has a gridobject for this one! If desktop=null, add grid-canvasitem to all desktops of this namedview,
+* otherwise only add it to the specified desktop.
+*/
+static Inkscape::CanvasGrid* 
+sp_namedview_add_grid(SPNamedView *nv, Inkscape::XML::Node *repr, SPDesktop *desktop) {
+    Inkscape::CanvasGrid* grid = NULL;
+    //check if namedview already has an object for this grid
+    for (GSList *l = nv->grids; l != NULL; l = l->next) {
+        Inkscape::CanvasGrid* g = (Inkscape::CanvasGrid*) l->data;
+        if (repr == g->repr) {
+            grid = g;
+            break;
+        }
+    }
+    
+    if (!grid) {
+        //create grid object
+        const char * gridtype = repr->attribute("type");
+        if (!gridtype) {
+            gridtype = "xygrid"; // use this as default gridtype when none is specified
+            repr->setAttribute("type", gridtype);
+        }
+        grid = Inkscape::CanvasGrid::NewGrid(nv, repr, gridtype);
+        nv->grids = g_slist_append(nv->grids, grid);
+    }
+    
+    if (!desktop) {
+        //add canvasitem to all desktops
+        for (GSList *l = nv->views; l != NULL; l = l->next) {
+            SPDesktop *dt = static_cast<SPDesktop*>(l->data);
+            grid->createCanvasItem(dt);
+        }
+    } else {
+        //add canvasitem only for specified desktop
+        grid->createCanvasItem(desktop);
+    }
+    grid->show();
+
+    return grid;
+}
+
 static void sp_namedview_child_added(SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref)
 {
     SPNamedView *nv = (SPNamedView *) object;
@@ -536,18 +578,7 @@ static void sp_namedview_child_added(SPObject *object, Inkscape::XML::Node *chil
 
     const gchar *id = child->attribute("id");
     if (!strcmp(child->name(), "inkscape:grid")) {
-        // check for which grid-type
-        Inkscape::CanvasGrid* addedgrid;
-        const char * gridtype = child->attribute("type");
-        if (!gridtype) {
-            gridtype = "xygrid"; // use this as default gridtype when none is specified
-            child->setAttribute("type", gridtype);
-        }
-        addedgrid = Inkscape::CanvasGrid::NewGrid( (SPDesktop*) nv->views->data, child, gridtype);
-        if (addedgrid) {
-            nv->grids = g_slist_append(nv->grids, addedgrid);
-            addedgrid->show();
-        }
+        sp_namedview_add_grid(nv, child, NULL);
     } else {
         SPObject *no = object->document->getObjectById(id);
         g_assert(SP_IS_OBJECT(no));
@@ -580,7 +611,6 @@ static void sp_namedview_child_added(SPObject *object, Inkscape::XML::Node *chil
 
 static void sp_namedview_remove_child(SPObject *object, Inkscape::XML::Node *child)
 {
-g_message("named view:: child removed");
     SPNamedView *nv = (SPNamedView *) object;
 
     if (!strcmp(child->name(), "inkscape:grid")) {
@@ -646,7 +676,7 @@ void SPNamedView::show(SPDesktop *desktop)
 
     views = g_slist_prepend(views, desktop);
 
-    SPCanvasItem * item = sp_canvas_item_new(sp_desktop_grid(desktop), INKSCAPE_TYPE_CXYGRID, NULL);
+    SPCanvasItem * item = sp_canvas_item_new(sp_desktop_gridgroup(desktop), INKSCAPE_TYPE_CXYGRID, NULL);
     // since we're keeping a copy, we need to bump up the ref count
     gtk_object_ref(GTK_OBJECT(item));
     gridviews = g_slist_prepend(gridviews, item);
@@ -656,17 +686,11 @@ void SPNamedView::show(SPDesktop *desktop)
     if (repr) {
         for (Inkscape::XML::Node * child = repr->firstChild() ; child != NULL; child = child->next() ) {
             if (!strcmp(child->name(), "inkscape:grid")) {
-                Inkscape::CanvasXYGrid* addedgrid = new Inkscape::CanvasXYGrid(desktop, child);
-                if (addedgrid) {
-                    grids = g_slist_append(grids, addedgrid);
-                    addedgrid->enable_snapping();
-                    addedgrid->show();
-                }
+                sp_namedview_add_grid(this, child, desktop);
             }
         }
     }
-
-
+    
     sp_namedview_setup_grid(this);
 }
 
index 2041adbf2d2d77a385d2d8630c0dc8f9926d4970..8a6955003cef2cbcafca642916e7543ba38d8d3b 100644 (file)
@@ -616,7 +616,7 @@ DocumentProperties::onNewGrid()
     Inkscape::XML::Node *repr = SP_OBJECT_REPR(sp_desktop_namedview(SP_ACTIVE_DESKTOP));
 
     Glib::ustring typestring = _grids_combo_gridtype.get_active_text();
-    CanvasGrid::writeNewGridToRepr(repr, typestring.c_str()); // FIXME ofcourse user should supply choice for gridtype 
+    CanvasGrid::writeNewGridToRepr(repr, typestring.c_str());
 }