From 02c3f3ebde37bbc650b2e8eb951e7037ed714360 Mon Sep 17 00:00:00 2001 From: johanengelen Date: Fri, 13 Apr 2007 14:41:49 +0000 Subject: [PATCH] New grids are almost ready to fly! --- src/desktop-handles.cpp | 4 +- src/desktop-handles.h | 2 +- src/desktop.cpp | 18 +++-- src/desktop.h | 5 +- src/display/canvas-axonomgrid.cpp | 9 ++- src/display/canvas-axonomgrid.h | 2 +- src/display/canvas-grid.cpp | 109 ++++++++++++++++---------- src/display/canvas-grid.h | 11 ++- src/sp-namedview.cpp | 68 ++++++++++------ src/ui/dialog/document-properties.cpp | 2 +- 10 files changed, 149 insertions(+), 81 deletions(-) diff --git a/src/desktop-handles.cpp b/src/desktop-handles.cpp index e2d36bb52..1241bfa02 100644 --- a/src/desktop-handles.cpp +++ b/src/desktop-handles.cpp @@ -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 * diff --git a/src/desktop-handles.h b/src/desktop-handles.h index 3633ef1f0..6001ba126 100644 --- a/src/desktop-handles.h +++ b/src/desktop-handles.h @@ -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); diff --git a/src/desktop.cpp b/src/desktop.cpp index 15d5bc9e3..561ab1cf0 100644 --- a/src/desktop.cpp +++ b/src/desktop.cpp @@ -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)); + } } } diff --git a/src/desktop.h b/src/desktop.h index 797e74a33..1aae2ebb6 100644 --- a/src/desktop.h +++ b/src/desktop.h @@ -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 _document_replaced_signal; diff --git a/src/display/canvas-axonomgrid.cpp b/src/display/canvas-axonomgrid.cpp index d384fb5d4..311c56f44 100644 --- a/src/display/canvas-axonomgrid.cpp +++ b/src/display/canvas-axonomgrid.cpp @@ -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; } diff --git a/src/display/canvas-axonomgrid.h b/src/display/canvas-axonomgrid.h index d560dad7c..0eaf914de 100644 --- a/src/display/canvas-axonomgrid.h +++ b/src/display/canvas-axonomgrid.h @@ -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); diff --git a/src/display/canvas-grid.cpp b/src/display/canvas-grid.cpp index f343077c3..6644092df 100644 --- a/src/display/canvas-grid.cpp +++ b/src/display/canvas-grid.cpp @@ -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 child to repr. +* writes an 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; diff --git a/src/display/canvas-grid.h b/src/display/canvas-grid.h index 54a57d3d0..db0f29f40 100644 --- a/src/display/canvas-grid.h +++ b/src/display/canvas-grid.h @@ -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); diff --git a/src/sp-namedview.cpp b/src/sp-namedview.cpp index e5cfa7924..c62c6b62e 100644 --- a/src/sp-namedview.cpp +++ b/src/sp-namedview.cpp @@ -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(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); } diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index 2041adbf2..8a6955003 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -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()); } -- 2.30.2