Code

Optionaly snap to invisible grid lines too (when zoomed out). See the grids tab in...
authordvlierop2 <dvlierop2@users.sourceforge.net>
Sat, 25 Apr 2009 16:57:08 +0000 (16:57 +0000)
committerdvlierop2 <dvlierop2@users.sourceforge.net>
Sat, 25 Apr 2009 16:57:08 +0000 (16:57 +0000)
src/display/canvas-axonomgrid.cpp
src/display/canvas-grid.cpp
src/display/canvas-grid.h
src/snapper.cpp
src/snapper.h

index 1a7c01c168a6caa94682b5b3a020c964f04efb59..71b22d2ad512d3beba51419e46fa0bb8443b43dd 100644 (file)
@@ -358,6 +358,11 @@ CanvasAxonomGrid::readRepr()
         snapper->setEnabled(strcmp(value,"false") != 0 && strcmp(value, "0") != 0);
     }
 
+    if ( (value = repr->attribute("snapvisiblegridlinesonly")) ) {
+               g_assert(snapper != NULL);
+               snapper->setSnapVisibleOnly(strcmp(value,"false") != 0 && strcmp(value, "0") != 0);
+       }
+
     for (GSList *l = canvasitems; l != NULL; l = l->next) {
         sp_canvas_item_request_update ( SP_CANVAS_ITEM(l->data) );
     }
@@ -685,16 +690,26 @@ CanvasAxonomGridSnapper::_getSnapLines(Geom::Point const &p) const
         return s;
     }
 
-    /* This is to make sure we snap to only visible grid lines */
-    double scaled_spacing_h = grid->spacing_ylines; // this is spacing of visible lines if screen pixels
-    double scaled_spacing_v = grid->lyw; // vertical
+    double spacing_h;
+    double spacing_v;
+
+    if (getSnapVisibleOnly()) {
+               // Only snapping to visible grid lines
+               spacing_h = grid->spacing_ylines; // this is the spacing of the visible grid lines measured in screen pixels
+               spacing_v = grid->lyw; // vertical
+               // convert screen pixels to px
+               // FIXME: after we switch to snapping dist in screen pixels, this will be unnecessary
+               SPDesktop const *dt = _snapmanager->getDesktop();
+               if (dt) {
+                       spacing_h /= dt->current_zoom();
+                       spacing_v /= dt->current_zoom();
+               }
+       } else {
+               // Snapping to any grid line, whether it's visible or not
+               spacing_h = grid->lengthy  /(grid->tan_angle[X] + grid->tan_angle[Z]);
+               spacing_v = grid->lengthy;
 
-    // convert screen pixels to px
-    // FIXME: after we switch to snapping dist in screen pixels, this will be unnecessary
-    if (SP_ACTIVE_DESKTOP) {
-        scaled_spacing_h /= SP_ACTIVE_DESKTOP->current_zoom();
-        scaled_spacing_v /= SP_ACTIVE_DESKTOP->current_zoom();
-    }
+       }
 
     // In an axonometric grid, any point will be surrounded by 6 grid lines:
     // - 2 vertical grid lines, one left and one right from the point
@@ -702,16 +717,16 @@ CanvasAxonomGridSnapper::_getSnapLines(Geom::Point const &p) const
     // - 2 angled x grid lines, one above and one below the point
 
     // Calculate the x coordinate of the vertical grid lines
-    Geom::Coord x_max = Inkscape::Util::round_to_upper_multiple_plus(p[Geom::X], scaled_spacing_h, grid->origin[Geom::X]);
-    Geom::Coord x_min = Inkscape::Util::round_to_lower_multiple_plus(p[Geom::X], scaled_spacing_h, grid->origin[Geom::X]);
+    Geom::Coord x_max = Inkscape::Util::round_to_upper_multiple_plus(p[Geom::X], spacing_h, grid->origin[Geom::X]);
+    Geom::Coord x_min = Inkscape::Util::round_to_lower_multiple_plus(p[Geom::X], spacing_h, grid->origin[Geom::X]);
 
     // Calculate the y coordinate of the intersection of the angled grid lines with the y-axis
     double y_proj_along_z = p[Geom::Y] - grid->tan_angle[Z]*(p[Geom::X] - grid->origin[Geom::X]);
     double y_proj_along_x = p[Geom::Y] + grid->tan_angle[X]*(p[Geom::X] - grid->origin[Geom::X]);
-    double y_proj_along_z_max = Inkscape::Util::round_to_upper_multiple_plus(y_proj_along_z, scaled_spacing_v, grid->origin[Geom::Y]);
-    double y_proj_along_z_min = Inkscape::Util::round_to_lower_multiple_plus(y_proj_along_z, scaled_spacing_v, grid->origin[Geom::Y]);
-    double y_proj_along_x_max = Inkscape::Util::round_to_upper_multiple_plus(y_proj_along_x, scaled_spacing_v, grid->origin[Geom::Y]);
-    double y_proj_along_x_min = Inkscape::Util::round_to_lower_multiple_plus(y_proj_along_x, scaled_spacing_v, grid->origin[Geom::Y]);
+    double y_proj_along_z_max = Inkscape::Util::round_to_upper_multiple_plus(y_proj_along_z, spacing_v, grid->origin[Geom::Y]);
+    double y_proj_along_z_min = Inkscape::Util::round_to_lower_multiple_plus(y_proj_along_z, spacing_v, grid->origin[Geom::Y]);
+    double y_proj_along_x_max = Inkscape::Util::round_to_upper_multiple_plus(y_proj_along_x, spacing_v, grid->origin[Geom::Y]);
+    double y_proj_along_x_min = Inkscape::Util::round_to_lower_multiple_plus(y_proj_along_x, spacing_v, grid->origin[Geom::Y]);
 
     // Calculate the versor for the angled grid lines
     Geom::Point vers_x = Geom::Point(1, -grid->tan_angle[X]);
index c971382b464a3f4c237d96ffd790b83c64fe1e8e..5037c0375a695e2d093023505a4613cdbe1c27b2 100644 (file)
@@ -324,6 +324,12 @@ CanvasGrid::newWidget()
         new Inkscape::UI::Widget::RegisteredCheckButton( _("_Enabled"),
                         _("Determines whether to snap to this grid or not. Can be 'on' for invisible grids."),
                          "enabled", _wr, false, repr, doc) );
+
+    Inkscape::UI::Widget::RegisteredCheckButton * _rcb_snap_visible_only = Gtk::manage(
+            new Inkscape::UI::Widget::RegisteredCheckButton( _("Snap to visible _grid lines only"),
+                            _("When zoomed out, not all grid lines will be displayed. Only the visible ones will be snapped to"),
+                             "snapvisiblegridlinesonly", _wr, true, repr, doc) );
+
     Inkscape::UI::Widget::RegisteredCheckButton * _rcb_visible = Gtk::manage(
         new Inkscape::UI::Widget::RegisteredCheckButton( _("_Visible"),
                         _("Determines whether the grid is displayed or not. Objects are still snapped to invisible grids."),
@@ -331,11 +337,13 @@ CanvasGrid::newWidget()
 
     vbox->pack_start(*_rcb_enabled, true, true);
     vbox->pack_start(*_rcb_visible, true, true);
+    vbox->pack_start(*_rcb_snap_visible_only, true, true);
     Gtk::Widget * gridwdg = newSpecificWidget();
     vbox->pack_start(*gridwdg, true, true);
 
     std::list<Gtk::Widget*> slaves;
     slaves.push_back(_rcb_visible);
+    slaves.push_back(_rcb_snap_visible_only);
     slaves.push_back(gridwdg);
     _rcb_enabled->setSlaveWidgets(slaves);
 
@@ -343,6 +351,7 @@ CanvasGrid::newWidget()
     _rcb_visible->setActive(visible);
     if (snapper != NULL) {
         _rcb_enabled->setActive(snapper->getEnabled());
+        _rcb_snap_visible_only->setActive(snapper->getSnapVisibleOnly());
     }
 
     return dynamic_cast<Gtk::Widget *> (vbox);
@@ -625,6 +634,11 @@ CanvasXYGrid::readRepr()
         snapper->setEnabled(strcmp(value,"false") != 0 && strcmp(value, "0") != 0);
     }
 
+    if ( (value = repr->attribute("snapvisiblegridlinesonly")) ) {
+               g_assert(snapper != NULL);
+               snapper->setSnapVisibleOnly(strcmp(value,"false") != 0 && strcmp(value, "0") != 0);
+       }
+
     for (GSList *l = canvasitems; l != NULL; l = l->next) {
         sp_canvas_item_request_update ( SP_CANVAS_ITEM(l->data) );
     }
@@ -979,23 +993,30 @@ CanvasXYGridSnapper::_getSnapLines(Geom::Point const &p) const
 
     for (unsigned int i = 0; i < 2; ++i) {
 
-        /* This is to make sure we snap to only visible grid lines */
-        double scaled_spacing = grid->sw[i]; // this is spacing of visible lines in screen pixels
-
-        // convert screen pixels to px
-        // FIXME: after we switch to snapping dist in screen pixels, this will be unnecessary
-        if (SP_ACTIVE_DESKTOP) {
-            scaled_spacing /= SP_ACTIVE_DESKTOP->current_zoom();
+       double spacing;
+
+       if (getSnapVisibleOnly()) {
+               // Only snapping to visible grid lines
+               spacing = grid->sw[i]; // this is the spacing of the visible grid lines measured in screen pixels
+                       // convert screen pixels to px
+                       // FIXME: after we switch to snapping dist in screen pixels, this will be unnecessary
+                       SPDesktop const *dt = _snapmanager->getDesktop();
+               if (dt) {
+                       spacing /= dt->current_zoom();
+               }
+        } else {
+               // Snapping to any grid line, whether it's visible or not
+               spacing = grid->spacing[i];
         }
 
         Geom::Coord rounded;
         Geom::Point point_on_line;
 
-        rounded = Inkscape::Util::round_to_upper_multiple_plus(p[i], scaled_spacing, grid->origin[i]);
+        rounded = Inkscape::Util::round_to_upper_multiple_plus(p[i], spacing, grid->origin[i]);
         point_on_line = i ? Geom::Point(0, rounded) : Geom::Point(rounded, 0);
         s.push_back(std::make_pair(component_vectors[i], point_on_line));
 
-        rounded = Inkscape::Util::round_to_lower_multiple_plus(p[i], scaled_spacing, grid->origin[i]);
+        rounded = Inkscape::Util::round_to_lower_multiple_plus(p[i], spacing, grid->origin[i]);
         point_on_line = i ? Geom::Point(0, rounded) : Geom::Point(rounded, 0);
         s.push_back(std::make_pair(component_vectors[i], point_on_line));
     }
index 750fef1b0ee7bf56b192bd39570a85801f735227..58cfbf735d63b9a5cdb9a32c9ca987fe02b863fd 100644 (file)
@@ -136,7 +136,7 @@ public:
 
     Geom::Point spacing; /**< Spacing between elements of the grid */
     bool scaled[2];    /**< Whether the grid is in scaled mode, which can
-                            be different in the X or Y direction, hense two
+                            be different in the X or Y direction, hence two
                             variables */
     Geom::Point ow;      /**< Transformed origin by the affine for the zoom */
     Geom::Point sw;      /**< Transformed spacing by the affine for the zoom */
index 2c646f4d64751bddf93023b6a303af95c9d05a8d..751b663e30f8393fbc83dc0d5f211a6fc892abe1 100644 (file)
@@ -20,7 +20,8 @@
  */
 Inkscape::Snapper::Snapper(SnapManager *sm, Geom::Coord const /*t*/) :
        _snapmanager(sm),
-       _snap_enabled(true)
+       _snap_enabled(true),
+       _snap_visible_only(true)
 {
     g_assert(_snapmanager != NULL);
 }
@@ -34,6 +35,11 @@ void Inkscape::Snapper::setEnabled(bool s)
     _snap_enabled = s;
 }
 
+void Inkscape::Snapper::setSnapVisibleOnly(bool s)
+{
+    _snap_visible_only = s;
+}
+
 /*
   Local Variables:
   mode:c++
index cbd52f0523d786399a3372e04a5a20d9503fadfe..110b3d36ad5292fa721e1db7e55b76af01c5ce19 100644 (file)
@@ -51,8 +51,11 @@ public:
     */
     virtual bool ThisSnapperMightSnap() const {return _snap_enabled;} // will likely be overridden by derived classes
 
-    void setEnabled(bool s); // This is only used for grids, for which snapping can be enabled individually
+    // These four methods are only used for grids, for which snapping can be enabled individually
+    void setEnabled(bool s);
+       void setSnapVisibleOnly(bool s);
     bool getEnabled() const {return _snap_enabled;}
+    bool getSnapVisibleOnly() const {return _snap_visible_only;}
 
     virtual void freeSnap(SnappedConstraints &/*sc*/,
                           SnapPreferences::PointType const &/*t*/,
@@ -111,8 +114,9 @@ public:
 protected:
        SnapManager *_snapmanager;
 
+       // This is only used for grids, for which snapping can be enabled individually
        bool _snap_enabled; ///< true if this snapper is enabled, otherwise false
-                                               // This is only used for grids, for which snapping can be enabled individually
+       bool _snap_visible_only;
 };
 
 }