summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMaximilian Albert <maximilian.albert@gmail.com>2008-01-11 19:01:50 +0000
committercilix42 <cilix42@users.sourceforge.net>2008-01-11 19:01:50 +0000
commit0e82b86bbfd6d5656431edbf20fa8b6f79515a04 (patch)
treee9c728ab9079678cf526dc228800767a2f16c5f6
parentCheck for perspective in document defs (to avoid hanging/crashes after vacuum... (diff)
downloadinkscape-0e82b86bbfd6d5656431edbf20fa8b6f79515a04.tar.gz
inkscape-0e82b86bbfd6d5656431edbf20fa8b6f79515a04.zip
Add possibility to convert objects (only rectangles and 3D boxes currently) to guidelines. Also see corresponding post on the mailing list; in particular, feel free to revert it if this is inappropriate during Frost phase.
(bzr r4462)
-rw-r--r--src/box3d-context.cpp9
-rw-r--r--src/box3d.cpp43
-rw-r--r--src/box3d.h2
-rw-r--r--src/menus-skeleton.h1
-rw-r--r--src/rect-context.cpp9
-rw-r--r--src/select-context.cpp7
-rw-r--r--src/selection-chemistry.cpp35
-rw-r--r--src/selection-chemistry.h1
-rw-r--r--src/sp-guide.cpp27
-rw-r--r--src/sp-guide.h3
-rw-r--r--src/sp-rect.cpp27
-rw-r--r--src/sp-rect.h2
-rw-r--r--src/verbs.cpp6
-rw-r--r--src/verbs.h1
14 files changed, 173 insertions, 0 deletions
diff --git a/src/box3d-context.cpp b/src/box3d-context.cpp
index 68480a00d..bbc8097f5 100644
--- a/src/box3d-context.cpp
+++ b/src/box3d-context.cpp
@@ -24,6 +24,7 @@
#include "document.h"
#include "sp-namedview.h"
#include "selection.h"
+#include "selection-chemistry.h"
#include "desktop-handles.h"
#include "snap.h"
#include "display/curve.h"
@@ -532,6 +533,14 @@ static gint sp_box3d_context_root_handler(SPEventContext *event_context, GdkEven
ret = true;
break;
+ case GDK_g:
+ case GDK_G:
+ if (MOD__SHIFT_ONLY) {
+ sp_selection_to_guides();
+ ret = true;
+ }
+ break;
+
case GDK_P:
{
if (MOD__SHIFT && MOD__CTRL) break; // Don't catch Shift+Ctrl+P (Preferences dialog)
diff --git a/src/box3d.cpp b/src/box3d.cpp
index 082c83bbd..631d5cfc1 100644
--- a/src/box3d.cpp
+++ b/src/box3d.cpp
@@ -32,6 +32,8 @@
#include "persp3d-reference.h"
#include "uri.h"
#include "2geom/geom.h"
+#include "sp-guide.h"
+#include "sp-namedview.h"
#include "desktop.h"
#include "macros.h"
@@ -1486,6 +1488,47 @@ box3d_convert_to_group(SPBox3D *box) {
return SP_GROUP(doc->getObjectByRepr(grepr));
}
+static void
+box3d_push_back_corner_pair(SPBox3D *box, std::list<std::pair<Geom::Point, Geom::Point> > &pts, int c1, int c2) {
+ pts.push_back(std::make_pair(box3d_get_corner_screen(box, c1).to_2geom(),
+ box3d_get_corner_screen(box, c2).to_2geom()));
+}
+
+void
+box3d_convert_to_guides(SPBox3D *box, bool write_undo) {
+ SPDocument *doc = SP_OBJECT_DOCUMENT(box);
+ //SPDesktop *desktop = inkscape_active_desktop();
+ //Inkscape::XML::Document *xml_doc = sp_document_repr_doc(doc);
+
+ std::list<std::pair<Geom::Point, Geom::Point> > pts;
+
+ /* perspective lines in X direction */
+ box3d_push_back_corner_pair(box, pts, 0, 1);
+ box3d_push_back_corner_pair(box, pts, 2, 3);
+ box3d_push_back_corner_pair(box, pts, 4, 5);
+ box3d_push_back_corner_pair(box, pts, 6, 7);
+
+ /* perspective lines in Y direction */
+ box3d_push_back_corner_pair(box, pts, 0, 2);
+ box3d_push_back_corner_pair(box, pts, 1, 3);
+ box3d_push_back_corner_pair(box, pts, 4, 6);
+ box3d_push_back_corner_pair(box, pts, 5, 7);
+
+ /* perspective lines in Z direction */
+ box3d_push_back_corner_pair(box, pts, 0, 4);
+ box3d_push_back_corner_pair(box, pts, 1, 5);
+ box3d_push_back_corner_pair(box, pts, 2, 6);
+ box3d_push_back_corner_pair(box, pts, 3, 7);
+
+ sp_guide_pt_pairs_to_guides(doc, pts);
+
+ SP_OBJECT(box)->deleteObject(true);
+
+ if (write_undo) {
+ sp_document_done(doc, SP_VERB_CONTEXT_3DBOX, _("Convert to guides"));
+ }
+}
+
/*
Local Variables:
mode:c++
diff --git a/src/box3d.h b/src/box3d.h
index 12d6bfc4b..bcbd975c5 100644
--- a/src/box3d.h
+++ b/src/box3d.h
@@ -82,6 +82,8 @@ Persp3D *box3d_get_perspective(SPBox3D const *box);
void box3d_switch_perspectives(SPBox3D *box, Persp3D *old_persp, Persp3D *new_persp, bool recompute_corners = false);
SPGroup *box3d_convert_to_group(SPBox3D *box);
+void box3d_convert_to_guides(SPBox3D *box, bool write_undo = true);
+
#endif /* __SP_BOX3D_H__ */
diff --git a/src/menus-skeleton.h b/src/menus-skeleton.h
index bdbbc51de..b96ee2302 100644
--- a/src/menus-skeleton.h
+++ b/src/menus-skeleton.h
@@ -171,6 +171,7 @@ static char const menus_skeleton[] =
" <verb verb-id=\"ObjectsFromPattern\" />\n"
" </submenu>\n"
" <verb verb-id=\"ObjectsToMarker\" />\n"
+" <verb verb-id=\"ObjectsToGuides\" />\n"
" <separator/>\n"
" <verb verb-id=\"SelectionRaise\" />\n"
" <verb verb-id=\"SelectionLower\" />\n"
diff --git a/src/rect-context.cpp b/src/rect-context.cpp
index 5969c1fb2..938b4496d 100644
--- a/src/rect-context.cpp
+++ b/src/rect-context.cpp
@@ -25,6 +25,7 @@
#include "document.h"
#include "sp-namedview.h"
#include "selection.h"
+#include "selection-chemistry.h"
#include "desktop-handles.h"
#include "snap.h"
#include "desktop.h"
@@ -413,6 +414,14 @@ static gint sp_rect_context_root_handler(SPEventContext *event_context, GdkEvent
}
break;
+ case GDK_g:
+ case GDK_G:
+ if (MOD__SHIFT_ONLY) {
+ sp_selection_to_guides();
+ ret = true;
+ }
+ break;
+
case GDK_Escape:
sp_desktop_selection(desktop)->clear();
//TODO: make dragging escapable by Esc
diff --git a/src/select-context.cpp b/src/select-context.cpp
index cdf63785c..48afadb2b 100644
--- a/src/select-context.cpp
+++ b/src/select-context.cpp
@@ -888,6 +888,13 @@ sp_select_context_root_handler(SPEventContext *event_context, GdkEvent *event)
ret = TRUE;
}
break;
+ case GDK_g:
+ case GDK_G:
+ if (MOD__SHIFT_ONLY) {
+ sp_selection_to_guides();
+ ret = true;
+ }
+ break;
default:
break;
}
diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp
index 56ef7b01f..fc2a6a271 100644
--- a/src/selection-chemistry.cpp
+++ b/src/selection-chemistry.cpp
@@ -72,12 +72,14 @@
#include <map>
#include "helper/units.h"
#include "sp-item.h"
+#include "box3d.h"
#include "unit-constants.h"
#include "xml/simple-document.h"
#include "sp-filter-reference.h"
#include "gradient-drag.h"
#include "uri-references.h"
#include "live_effects/lpeobject.h"
+#include "sp-rect.h"
using NR::X;
using NR::Y;
@@ -2440,6 +2442,39 @@ void sp_selection_to_marker(bool apply)
_("Objects to marker"));
}
+void sp_selection_to_guides()
+{
+ SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+ if (desktop == NULL)
+ return;
+
+ SPDocument *doc = sp_desktop_document(desktop);
+ Inkscape::Selection *selection = sp_desktop_selection(desktop);
+ // we need to copy the list because it gets reset when objects are deleted
+ GSList *items = g_slist_copy((GSList *) selection->itemList());
+
+ bool performed = false;
+ for (GSList const *i = items; i != NULL; i = i->next) {
+ if (SP_IS_RECT(i->data)) {
+ sp_rect_convert_to_guides(SP_RECT(i->data), false);
+ performed = true;
+ } else if (SP_IS_BOX3D(i->data)) {
+ box3d_convert_to_guides(SP_BOX3D(i->data), false);
+ performed = true;
+ }
+ }
+
+ if (!performed) {
+ desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>object(s)</b> to convert to guides (selection must contain at least one rectangle or 3D box)."));
+ return;
+ }
+
+ if (performed) {
+ sp_document_done (doc, SP_VERB_EDIT_SELECTION_2_GUIDES,
+ _("Objects to guides"));
+ }
+}
+
void
sp_selection_tile(bool apply)
{
diff --git a/src/selection-chemistry.h b/src/selection-chemistry.h
index 09f957332..0dc1da7e7 100644
--- a/src/selection-chemistry.h
+++ b/src/selection-chemistry.h
@@ -36,6 +36,7 @@ void sp_selection_unlink();
void sp_select_clone_original ();
void sp_selection_to_marker(bool apply = true);
+void sp_selection_to_guides();
void sp_selection_tile(bool apply = true);
void sp_selection_untile();
diff --git a/src/sp-guide.cpp b/src/sp-guide.cpp
index 26d60601c..68e322178 100644
--- a/src/sp-guide.cpp
+++ b/src/sp-guide.cpp
@@ -34,6 +34,7 @@
#include "desktop.h"
#include "sp-namedview.h"
#include <2geom/angle.h>
+#include "document.h"
using std::vector;
@@ -235,6 +236,32 @@ static void sp_guide_set(SPObject *object, unsigned int key, const gchar *value)
}
}
+SPGuide *
+sp_guide_create(SPDocument *doc, Geom::Point const &pt1, Geom::Point const &pt2) {
+ SPDesktop *desktop = inkscape_active_desktop();
+ Inkscape::XML::Document *xml_doc = sp_document_repr_doc(doc);
+
+ Inkscape::XML::Node *repr = xml_doc->createElement("sodipodi:guide");
+
+ Geom::Point n = Geom::rot90(pt2 - pt1);
+
+ sp_repr_set_point(repr, "position", pt1);
+ sp_repr_set_point(repr, "orientation", n);
+
+ SP_OBJECT_REPR(desktop->namedview)->appendChild(repr);
+ Inkscape::GC::release(repr);
+
+ SPGuide *guide= SP_GUIDE(doc->getObjectByRepr(repr));
+ return guide;
+}
+
+void
+sp_guide_pt_pairs_to_guides(SPDocument *doc, std::list<std::pair<Geom::Point, Geom::Point> > &pts) {
+ for (std::list<std::pair<Geom::Point, Geom::Point> >::iterator i = pts.begin(); i != pts.end(); ++i) {
+ sp_guide_create(doc, (*i).first, (*i).second);
+ }
+}
+
void sp_guide_show(SPGuide *guide, SPCanvasGroup *group, GCallback handler)
{
SPCanvasItem *item = sp_guideline_new(group, guide->point_on_line, guide->normal_to_line.to_2geom());
diff --git a/src/sp-guide.h b/src/sp-guide.h
index dbbebadb7..a9b04dfaa 100644
--- a/src/sp-guide.h
+++ b/src/sp-guide.h
@@ -45,6 +45,9 @@ struct SPGuideClass {
GType sp_guide_get_type();
+SPGuide *sp_guide_create(SPDesktop *desktop, Geom::Point const &pt1, Geom::Point const &pt2);
+void sp_guide_pt_pairs_to_guides(SPDocument *doc, std::list<std::pair<Geom::Point, Geom::Point> > &pts);
+
void sp_guide_show(SPGuide *guide, SPCanvasGroup *group, GCallback handler);
void sp_guide_hide(SPGuide *guide, SPCanvas *canvas);
void sp_guide_sensitize(SPGuide *guide, SPCanvas *canvas, gboolean sensitive);
diff --git a/src/sp-rect.cpp b/src/sp-rect.cpp
index d9caebd5a..e8e04cc51 100644
--- a/src/sp-rect.cpp
+++ b/src/sp-rect.cpp
@@ -28,6 +28,7 @@
#include "sp-rect.h"
#include <glibmm/i18n.h>
#include "xml/repr.h"
+#include "sp-guide.h"
#define noRECT_VERBOSE
@@ -578,6 +579,32 @@ static void sp_rect_snappoints(SPItem const *item, SnapPointsIter p)
*p = NR::Point(rect->x.computed + rect->width.computed, rect->y.computed) * i2d;
}
+void
+sp_rect_convert_to_guides(SPRect *rect, bool write_undo) {
+ SPDocument *doc = SP_OBJECT_DOCUMENT(rect);
+ std::list<std::pair<Geom::Point, Geom::Point> > pts;
+
+ NR::Matrix const i2d (sp_item_i2d_affine(SP_ITEM(rect)));
+
+ NR::Point A1(NR::Point(rect->x.computed, rect->y.computed) * i2d);
+ NR::Point A2(NR::Point(rect->x.computed, rect->y.computed + rect->height.computed) * i2d);
+ NR::Point A3(NR::Point(rect->x.computed + rect->width.computed, rect->y.computed + rect->height.computed) * i2d);
+ NR::Point A4(NR::Point(rect->x.computed + rect->width.computed, rect->y.computed) * i2d);
+
+ pts.push_back(std::make_pair(A1.to_2geom(), A2.to_2geom()));
+ pts.push_back(std::make_pair(A2.to_2geom(), A3.to_2geom()));
+ pts.push_back(std::make_pair(A3.to_2geom(), A4.to_2geom()));
+ pts.push_back(std::make_pair(A4.to_2geom(), A1.to_2geom()));
+
+ sp_guide_pt_pairs_to_guides(doc, pts);
+
+ SP_OBJECT(rect)->deleteObject(true);
+
+ if (write_undo) {
+ sp_document_done(doc, SP_VERB_CONTEXT_RECT, _("Convert to guides"));
+ }
+}
+
/*
Local Variables:
mode:c++
diff --git a/src/sp-rect.h b/src/sp-rect.h
index 4cf3b24ba..0133922e8 100644
--- a/src/sp-rect.h
+++ b/src/sp-rect.h
@@ -62,4 +62,6 @@ gdouble sp_rect_get_visible_height (SPRect *rect);
void sp_rect_compensate_rxry (SPRect *rect, NR::Matrix xform);
+void sp_rect_convert_to_guides(SPRect *rect, bool write_undo = true);
+
#endif
diff --git a/src/verbs.cpp b/src/verbs.cpp
index 53650a262..736ddc3d5 100644
--- a/src/verbs.cpp
+++ b/src/verbs.cpp
@@ -888,6 +888,9 @@ EditVerb::perform(SPAction *action, void *data, void */*pdata*/)
case SP_VERB_EDIT_SELECTION_2_MARKER:
sp_selection_to_marker();
break;
+ case SP_VERB_EDIT_SELECTION_2_GUIDES:
+ sp_selection_to_guides();
+ break;
case SP_VERB_EDIT_TILE:
sp_selection_tile();
break;
@@ -2191,6 +2194,9 @@ Verb *Verb::_base_verbs[] = {
// TRANSLATORS: Convert selection to a line marker
new EditVerb(SP_VERB_EDIT_SELECTION_2_MARKER, "ObjectsToMarker", N_("Objects to _Marker"),
N_("Convert selection to a line marker"), NULL),
+ // TRANSLATORS: Convert selection to a collection of guidelines
+ new EditVerb(SP_VERB_EDIT_SELECTION_2_GUIDES, "ObjectsToGuides", N_("Objects to Gu_ides"),
+ N_("Convert selected objects to a collection of guidelines aligned with their edges"), NULL),
// TRANSLATORS: Convert selection to a rectangle with tiled pattern fill
new EditVerb(SP_VERB_EDIT_TILE, "ObjectsToPattern", N_("Objects to Patter_n"),
N_("Convert selection to a rectangle with tiled pattern fill"), NULL),
diff --git a/src/verbs.h b/src/verbs.h
index 9f5cbe3c8..104d4db0d 100644
--- a/src/verbs.h
+++ b/src/verbs.h
@@ -67,6 +67,7 @@ enum {
SP_VERB_EDIT_UNLINK_CLONE,
SP_VERB_EDIT_CLONE_SELECT_ORIGINAL,
SP_VERB_EDIT_SELECTION_2_MARKER,
+ SP_VERB_EDIT_SELECTION_2_GUIDES,
SP_VERB_EDIT_TILE,
SP_VERB_EDIT_UNTILE,
SP_VERB_EDIT_CLEAR_ALL,