From 156cf3323a936c7dfccd9e09458cd8b5d174b7fe Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 5 Oct 2014 19:24:27 -0400 Subject: Move more UI code into ui/ (bzr r13341.1.253) --- src/CMakeLists.txt | 9 - src/Makefile_insert | 5 - src/desktop-events.cpp | 2 +- src/desktop.cpp | 2 +- src/display/snap-indicator.cpp | 2 +- src/draw-anchor.cpp | 105 -- src/draw-anchor.h | 52 - src/extension/internal/metafile-inout.cpp | 6 +- src/knot.cpp | 2 +- src/knotholder.h | 9 +- src/live_effects/effect.cpp | 2 +- src/live_effects/lpe-envelope-perspective.cpp | 2 +- src/live_effects/lpe-fillet-chamfer.cpp | 2 +- src/live_effects/lpe-lattice2.cpp | 2 +- src/live_effects/parameter/path.cpp | 4 +- src/live_effects/parameter/pointreseteable.cpp | 2 +- src/object-edit.cpp | 1397 ----------------------- src/object-edit.h | 83 -- src/selection-chemistry.cpp | 4 +- src/shape-editor.cpp | 171 --- src/shape-editor.h | 67 -- src/sp-lpe-item.cpp | 4 +- src/tool-factory.h | 40 - src/tools-switch.cpp | 195 ---- src/tools-switch.h | 64 -- src/ui/CMakeLists.txt | 8 + src/ui/Makefile_insert | 9 + src/ui/clipboard.cpp | 2 +- src/ui/dialog/align-and-distribute.cpp | 2 +- src/ui/dialog/document-properties.cpp | 4 +- src/ui/dialog/objects.cpp | 2 +- src/ui/dialog/spellcheck.cpp | 2 +- src/ui/draw-anchor.cpp | 105 ++ src/ui/draw-anchor.h | 52 + src/ui/object-edit.cpp | 1399 ++++++++++++++++++++++++ src/ui/object-edit.h | 84 ++ src/ui/shape-editor.cpp | 177 +++ src/ui/shape-editor.h | 71 ++ src/ui/tool-factory.h | 40 + src/ui/tool/node.cpp | 2 +- src/ui/tools-switch.cpp | 196 ++++ src/ui/tools-switch.h | 64 ++ src/ui/tools/arc-tool.cpp | 4 +- src/ui/tools/box3d-tool.cpp | 4 +- src/ui/tools/calligraphic-tool.cpp | 2 +- src/ui/tools/connector-tool.cpp | 2 +- src/ui/tools/dropper-tool.cpp | 2 +- src/ui/tools/eraser-tool.cpp | 2 +- src/ui/tools/flood-tool.cpp | 4 +- src/ui/tools/freehand-base.cpp | 2 +- src/ui/tools/gradient-tool.cpp | 2 +- src/ui/tools/lpe-tool.cpp | 4 +- src/ui/tools/measure-tool.cpp | 2 +- src/ui/tools/mesh-tool.cpp | 2 +- src/ui/tools/node-tool.cpp | 4 +- src/ui/tools/pen-tool.cpp | 6 +- src/ui/tools/pencil-tool.cpp | 4 +- src/ui/tools/rect-tool.cpp | 4 +- src/ui/tools/select-tool.cpp | 4 +- src/ui/tools/spiral-tool.cpp | 4 +- src/ui/tools/spray-tool.cpp | 2 +- src/ui/tools/star-tool.cpp | 4 +- src/ui/tools/text-tool.cpp | 4 +- src/ui/tools/tool-base.cpp | 4 +- src/ui/tools/tool-base.h | 4 +- src/ui/tools/tweak-tool.cpp | 2 +- src/ui/tools/zoom-tool.cpp | 2 +- src/vanishing-point.cpp | 2 +- src/verbs.cpp | 4 +- src/widgets/lpe-toolbar.cpp | 2 +- src/widgets/pencil-toolbar.cpp | 2 +- src/widgets/sp-color-notebook.cpp | 2 +- src/widgets/toolbox.cpp | 2 +- 73 files changed, 2284 insertions(+), 2262 deletions(-) delete mode 100644 src/draw-anchor.cpp delete mode 100644 src/draw-anchor.h delete mode 100644 src/object-edit.cpp delete mode 100644 src/object-edit.h delete mode 100644 src/shape-editor.cpp delete mode 100644 src/shape-editor.h delete mode 100644 src/tool-factory.h delete mode 100644 src/tools-switch.cpp delete mode 100644 src/tools-switch.h create mode 100644 src/ui/draw-anchor.cpp create mode 100644 src/ui/draw-anchor.h create mode 100644 src/ui/object-edit.cpp create mode 100644 src/ui/object-edit.h create mode 100644 src/ui/shape-editor.cpp create mode 100644 src/ui/shape-editor.h create mode 100644 src/ui/tool-factory.h create mode 100644 src/ui/tools-switch.cpp create mode 100644 src/ui/tools-switch.h (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1cd2ff3a6..c77a9bf63 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -192,7 +192,6 @@ set(inkscape_SRC document-undo.cpp document.cpp doxygen-main.cpp - draw-anchor.cpp ege-color-prof-tracker.cpp event-log.cpp extract-uri.cpp @@ -226,7 +225,6 @@ set(inkscape_SRC message-context.cpp message-stack.cpp mod360.cpp - object-edit.cpp object-hierarchy.cpp object-snapper.cpp path-chemistry.cpp @@ -249,7 +247,6 @@ set(inkscape_SRC selection.cpp seltrans-handles.cpp seltrans.cpp - shape-editor.cpp shortcuts.cpp snap-preferences.cpp snap.cpp @@ -263,7 +260,6 @@ set(inkscape_SRC svg-view.cpp text-chemistry.cpp text-editing.cpp - tools-switch.cpp transf_mat_3x4.cpp unclump.cpp unicoderange.cpp @@ -309,7 +305,6 @@ set(inkscape_SRC document-subset.h document-undo.h document.h - draw-anchor.h ege-color-prof-tracker.h enums.h event-log.h @@ -364,7 +359,6 @@ set(inkscape_SRC mod360-test.h mod360.h number-opt-number.h - object-edit.h object-hierarchy.h object-snapper.h path-chemistry.h @@ -395,7 +389,6 @@ set(inkscape_SRC selection.h seltrans-handles.h seltrans.h - shape-editor.h shortcuts.h snap-candidate.h snap-enums.h @@ -420,8 +413,6 @@ set(inkscape_SRC text-chemistry.h text-editing.h text-tag-attributes.h - tool-factory.h - tools-switch.h transf_mat_3x4.h unclump.h undo-stack-observer.h diff --git a/src/Makefile_insert b/src/Makefile_insert index 762535cb5..d6db76eea 100644 --- a/src/Makefile_insert +++ b/src/Makefile_insert @@ -37,7 +37,6 @@ ink_common_sources += \ document-subset.cpp document-subset.h \ document-undo.cpp document-undo.h \ doxygen-main.cpp \ - draw-anchor.cpp draw-anchor.h \ ege-color-prof-tracker.cpp ege-color-prof-tracker.h \ enums.h \ event-log.cpp event-log.h event.h \ @@ -84,7 +83,6 @@ ink_common_sources += \ message.h \ message-stack.cpp message-stack.h \ mod360.cpp mod360.h \ - object-edit.cpp object-edit.h \ object-hierarchy.cpp object-hierarchy.h \ object-snapper.cpp object-snapper.h \ path-chemistry.cpp path-chemistry.h \ @@ -111,7 +109,6 @@ ink_common_sources += \ selection-describer.cpp selection-describer.h \ seltrans.cpp seltrans.h \ seltrans-handles.cpp seltrans-handles.h \ - shape-editor.cpp shape-editor.h \ shortcuts.cpp shortcuts.h \ snap.cpp snap.h \ snap-enums.h snap-candidate.h \ @@ -214,8 +211,6 @@ ink_common_sources += \ text-chemistry.cpp text-chemistry.h \ text-editing.cpp text-editing.h \ text-tag-attributes.h \ - tool-factory.h \ - tools-switch.cpp tools-switch.h \ transf_mat_3x4.cpp transf_mat_3x4.h \ unclump.cpp unclump.h \ undo-stack-observer.h \ diff --git a/src/desktop-events.cpp b/src/desktop-events.cpp index 91023d213..5d8ea8b9f 100644 --- a/src/desktop-events.cpp +++ b/src/desktop-events.cpp @@ -40,7 +40,7 @@ #include "display/sp-canvas.h" #include "sp-guide.h" #include "sp-namedview.h" -#include "tools-switch.h" +#include "ui/tools-switch.h" #include "verbs.h" #include "widgets/desktop-widget.h" #include "xml/repr.h" diff --git a/src/desktop.cpp b/src/desktop.cpp index b72e9c776..74dea3ca1 100644 --- a/src/desktop.cpp +++ b/src/desktop.cpp @@ -72,7 +72,7 @@ #include "sp-namedview.h" #include "sp-root.h" #include "sp-defs.h" -#include "tool-factory.h" +#include "ui/tool-factory.h" #include "widgets/desktop-widget.h" #include "xml/repr.h" #include "helper/action.h" //sp_action_perform diff --git a/src/display/snap-indicator.cpp b/src/display/snap-indicator.cpp index 3a8358174..2632d69db 100644 --- a/src/display/snap-indicator.cpp +++ b/src/display/snap-indicator.cpp @@ -22,7 +22,7 @@ #include "knot.h" #include "preferences.h" #include -#include "tools-switch.h" +#include "ui/tools-switch.h" #include "enums.h" namespace Inkscape { diff --git a/src/draw-anchor.cpp b/src/draw-anchor.cpp deleted file mode 100644 index 6b02bb607..000000000 --- a/src/draw-anchor.cpp +++ /dev/null @@ -1,105 +0,0 @@ -/** \file - * Anchors implementation. - */ - -/* - * Authors: - * Copyright (C) 2000 Lauris Kaplinski - * Copyright (C) 2000-2001 Ximian, Inc. - * Copyright (C) 2002 Lauris Kaplinski - * Copyright (C) 2004 Monash University - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - - -#include "draw-anchor.h" -#include "desktop.h" -#include "desktop-handles.h" -#include "ui/tools/tool-base.h" -#include "ui/tools/lpe-tool.h" -#include "display/sodipodi-ctrl.h" -#include "display/curve.h" -#include "ui/control-manager.h" - -using Inkscape::ControlManager; - -#define FILL_COLOR_NORMAL 0xffffff7f -#define FILL_COLOR_MOUSEOVER 0xff0000ff - -/** - * Creates an anchor object and initializes it. - */ -SPDrawAnchor *sp_draw_anchor_new(Inkscape::UI::Tools::FreehandBase *dc, SPCurve *curve, bool start, Geom::Point delta) -{ - if (SP_IS_LPETOOL_CONTEXT(dc)) { - // suppress all kinds of anchors in LPEToolContext - return NULL; - } - - SPDrawAnchor *a = g_new(SPDrawAnchor, 1); - - a->dc = dc; - a->curve = curve; - curve->ref(); - a->start = start; - a->active = FALSE; - a->dp = delta; - a->ctrl = ControlManager::getManager().createControl(sp_desktop_controls(&dc->getDesktop()), Inkscape::CTRL_TYPE_ANCHOR); - - SP_CTRL(a->ctrl)->moveto(delta); - - ControlManager::getManager().track(a->ctrl); - - return a; -} - -/** - * Destroys the anchor's canvas item and frees the anchor object. - */ -SPDrawAnchor *sp_draw_anchor_destroy(SPDrawAnchor *anchor) -{ - if (anchor->curve) { - anchor->curve->unref(); - } - if (anchor->ctrl) { - sp_canvas_item_destroy(anchor->ctrl); - } - g_free(anchor); - return NULL; -} - -/** - * Test if point is near anchor, if so fill anchor on canvas and return - * pointer to it or NULL. - */ -SPDrawAnchor *sp_draw_anchor_test(SPDrawAnchor *anchor, Geom::Point w, bool activate) -{ - SPCtrl *ctrl = SP_CTRL(anchor->ctrl); - - if ( activate && ( Geom::LInfty( w - anchor->dc->getDesktop().d2w(anchor->dp) ) <= (ctrl->box.width() / 2.0) ) ) { - if (!anchor->active) { - g_object_set(anchor->ctrl, "fill_color", FILL_COLOR_MOUSEOVER, NULL); - anchor->active = TRUE; - } - return anchor; - } - - if (anchor->active) { - g_object_set(anchor->ctrl, "fill_color", FILL_COLOR_NORMAL, NULL); - anchor->active = FALSE; - } - return NULL; -} - - -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/draw-anchor.h b/src/draw-anchor.h deleted file mode 100644 index 1f7b55920..000000000 --- a/src/draw-anchor.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef SEEN_DRAW_ANCHOR_H -#define SEEN_DRAW_ANCHOR_H - -/** \file - * Drawing anchors. - */ - -#include <2geom/point.h> - -namespace Inkscape { -namespace UI { -namespace Tools { - -class FreehandBase; - -} -} -} - -class SPCurve; -struct SPCanvasItem; - -/// The drawing anchor. -/// \todo Make this a regular knot, this will allow to set statusbar tips. -struct SPDrawAnchor { - Inkscape::UI::Tools::FreehandBase *dc; - SPCurve *curve; - unsigned int start : 1; - unsigned int active : 1; - Geom::Point dp; - SPCanvasItem *ctrl; -}; - - -SPDrawAnchor *sp_draw_anchor_new(Inkscape::UI::Tools::FreehandBase *dc, SPCurve *curve, bool start, - Geom::Point delta); -SPDrawAnchor *sp_draw_anchor_destroy(SPDrawAnchor *anchor); -SPDrawAnchor *sp_draw_anchor_test(SPDrawAnchor *anchor, Geom::Point w, bool activate); - - -#endif /* !SEEN_DRAW_ANCHOR_H */ - -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/extension/internal/metafile-inout.cpp b/src/extension/internal/metafile-inout.cpp index 162ad8b7d..534b33a30 100644 --- a/src/extension/internal/metafile-inout.cpp +++ b/src/extension/internal/metafile-inout.cpp @@ -30,7 +30,7 @@ #include "style.h" #include "document.h" #include "util/units.h" -#include "shape-editor.h" +#include "ui/shape-editor.h" #include "sp-namedview.h" #include "document-undo.h" #include "inkscape.h" @@ -202,7 +202,7 @@ void Metafile::setViewBoxIfMissing(SPDocument *doc) { // Scale and translate objects double scale = Inkscape::Util::Quantity::convert(1, "px", doc_unit); - ShapeEditor::blockSetItem(true); + Inkscape::UI::ShapeEditor::blockSetItem(true); double dh; if(SP_ACTIVE_DOCUMENT){ // for file menu open or import, or paste from clipboard dh = SP_ACTIVE_DOCUMENT->getHeight().value("px"); @@ -223,7 +223,7 @@ void Metafile::setViewBoxIfMissing(SPDocument *doc) { prefs->setBool("/options/transform/gradient", true); doc->getRoot()->scaleChildItemsRec(Geom::Scale(scale), Geom::Point(0, dh)); - ShapeEditor::blockSetItem(false); + Inkscape::UI::ShapeEditor::blockSetItem(false); // restore options prefs->setBool("/options/transform/stroke", transform_stroke); diff --git a/src/knot.cpp b/src/knot.cpp index 4476ad424..4118873c1 100644 --- a/src/knot.cpp +++ b/src/knot.cpp @@ -27,7 +27,7 @@ #include "preferences.h" #include "message-stack.h" #include "message-context.h" -#include "tools-switch.h" +#include "ui/tools-switch.h" #include "ui/tools/tool-base.h" #include "ui/tools/node-tool.h" #include diff --git a/src/knotholder.h b/src/knotholder.h index d33adb610..f1bacebe5 100644 --- a/src/knotholder.h +++ b/src/knotholder.h @@ -22,6 +22,9 @@ #include namespace Inkscape { +namespace UI { +class ShapeEditor; +} namespace XML { class Node; } @@ -58,9 +61,9 @@ public: bool knot_mouseover() const; - friend class ShapeEditor; - friend class Inkscape::LivePathEffect::PowerStrokePointArrayParamKnotHolderEntity; - friend class Inkscape::LivePathEffect::FilletPointArrayParamKnotHolderEntity; + friend class Inkscape::UI::ShapeEditor; // FIXME why? + friend class Inkscape::LivePathEffect::PowerStrokePointArrayParamKnotHolderEntity; // why? + friend class Inkscape::LivePathEffect::FilletPointArrayParamKnotHolderEntity; // why? protected: diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 3e3f8540a..0885ad6f0 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -74,7 +74,7 @@ #include "xml/document.h" #include #include "ui/tools/pen-tool.h" -#include "tools-switch.h" +#include "ui/tools-switch.h" #include "message-stack.h" #include "desktop.h" #include "knotholder.h" diff --git a/src/live_effects/lpe-envelope-perspective.cpp b/src/live_effects/lpe-envelope-perspective.cpp index f847dddc5..c62dbbf6a 100644 --- a/src/live_effects/lpe-envelope-perspective.cpp +++ b/src/live_effects/lpe-envelope-perspective.cpp @@ -19,7 +19,7 @@ #include "helper/geom.h" #include "display/curve.h" #include "svg/svg.h" -#include +#include "ui/tools-switch.h" #include #include "desktop.h" diff --git a/src/live_effects/lpe-fillet-chamfer.cpp b/src/live_effects/lpe-fillet-chamfer.cpp index 3f1fa382e..f15bf9215 100644 --- a/src/live_effects/lpe-fillet-chamfer.cpp +++ b/src/live_effects/lpe-fillet-chamfer.cpp @@ -29,7 +29,7 @@ // for programmatically updating knots #include "selection.h" -#include "tools-switch.h" +#include "ui/tools-switch.h" #include "ui/tool/control-point-selection.h" #include "ui/tool/selectable-control-point.h" #include "ui/tool/node.h" diff --git a/src/live_effects/lpe-lattice2.cpp b/src/live_effects/lpe-lattice2.cpp index 9dad78f6e..8fadd79ed 100644 --- a/src/live_effects/lpe-lattice2.cpp +++ b/src/live_effects/lpe-lattice2.cpp @@ -32,7 +32,7 @@ #include <2geom/d2.h> #include <2geom/piecewise.h> #include <2geom/transforms.h> -#include +#include "ui/tools-switch.h" #include "desktop.h" // TODO: should be factored out (see below) diff --git a/src/live_effects/parameter/path.cpp b/src/live_effects/parameter/path.cpp index 8095056b7..74d99918a 100644 --- a/src/live_effects/parameter/path.cpp +++ b/src/live_effects/parameter/path.cpp @@ -28,8 +28,8 @@ #include "document-undo.h" // needed for on-canvas editting: -#include "tools-switch.h" -#include "shape-editor.h" +#include "ui/tools-switch.h" +#include "ui/shape-editor.h" #include "desktop-handles.h" #include "selection.h" // clipboard support diff --git a/src/live_effects/parameter/pointreseteable.cpp b/src/live_effects/parameter/pointreseteable.cpp index ec36fc035..c0f8858b8 100644 --- a/src/live_effects/parameter/pointreseteable.cpp +++ b/src/live_effects/parameter/pointreseteable.cpp @@ -15,7 +15,7 @@ #include "verbs.h" #include "knotholder.h" #include -#include "tools-switch.h" +#include "ui/tools-switch.h" #include "ui/tools/node-tool.h" // needed for on-canvas editting: diff --git a/src/object-edit.cpp b/src/object-edit.cpp deleted file mode 100644 index 14a5bd3d5..000000000 --- a/src/object-edit.cpp +++ /dev/null @@ -1,1397 +0,0 @@ -/* - * Node editing extension to objects - * - * Authors: - * Lauris Kaplinski - * Mitsuru Oka - * Maximilian Albert - * Abhishek Sharma - * - * Licensed under GNU GPL - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - - - -#include "sp-item.h" -#include "sp-rect.h" -#include "box3d.h" -#include "sp-ellipse.h" -#include "sp-star.h" -#include "sp-spiral.h" -#include "sp-offset.h" -#include "sp-flowtext.h" -#include "preferences.h" -#include "style.h" -#include "desktop.h" -#include "desktop-handles.h" -#include "sp-namedview.h" -#include "live_effects/effect.h" -#include "sp-pattern.h" -#include "sp-path.h" -#include -#include "object-edit.h" -#include "xml/repr.h" -#include <2geom/math-utils.h> -#include "knot-holder-entity.h" - -#define sp_round(v,m) (((v) < 0.0) ? ((ceil((v) / (m) - 0.5)) * (m)) : ((floor((v) / (m) + 0.5)) * (m))) - -namespace { - -static KnotHolder *sp_lpe_knot_holder(SPItem *item, SPDesktop *desktop) -{ - KnotHolder *knot_holder = new KnotHolder(desktop, item, NULL); - - Inkscape::LivePathEffect::Effect *effect = SP_LPE_ITEM(item)->getCurrentLPE(); - effect->addHandles(knot_holder, desktop, item); - - return knot_holder; -} - -} // namespace - -namespace Inkscape { - -KnotHolder *createKnotHolder(SPItem *item, SPDesktop *desktop) -{ - KnotHolder *knotholder = NULL; - - if (SP_IS_LPE_ITEM(item) && - SP_LPE_ITEM(item)->getCurrentLPE() && - SP_LPE_ITEM(item)->getCurrentLPE()->isVisible() && - SP_LPE_ITEM(item)->getCurrentLPE()->providesKnotholder()) { - knotholder = sp_lpe_knot_holder(item, desktop); - } else if (SP_IS_RECT(item)) { - knotholder = new RectKnotHolder(desktop, item, NULL); - } else if (SP_IS_BOX3D(item)) { - knotholder = new Box3DKnotHolder(desktop, item, NULL); - } else if (SP_IS_GENERICELLIPSE(item)) { - knotholder = new ArcKnotHolder(desktop, item, NULL); - } else if (SP_IS_STAR(item)) { - knotholder = new StarKnotHolder(desktop, item, NULL); - } else if (SP_IS_SPIRAL(item)) { - knotholder = new SpiralKnotHolder(desktop, item, NULL); - } else if (SP_IS_OFFSET(item)) { - knotholder = new OffsetKnotHolder(desktop, item, NULL); - } else if (SP_IS_FLOWTEXT(item) && SP_FLOWTEXT(item)->has_internal_frame()) { - knotholder = new FlowtextKnotHolder(desktop, SP_FLOWTEXT(item)->get_frame(NULL), NULL); - } else if ((item->style->fill.isPaintserver() && SP_IS_PATTERN(item->style->getFillPaintServer())) || - (item->style->stroke.isPaintserver() && SP_IS_PATTERN(item->style->getStrokePaintServer()))) { - knotholder = new KnotHolder(desktop, item, NULL); - knotholder->add_pattern_knotholder(); - } - - return knotholder; -} - -} // Inkscape - -/* SPRect */ - -/* handle for horizontal rounding radius */ -class RectKnotHolderEntityRX : public KnotHolderEntity { -public: - virtual Geom::Point knot_get() const; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); - virtual void knot_click(unsigned int state); -}; - -/* handle for vertical rounding radius */ -class RectKnotHolderEntityRY : public KnotHolderEntity { -public: - virtual Geom::Point knot_get() const; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); - virtual void knot_click(unsigned int state); -}; - -/* handle for width/height adjustment */ -class RectKnotHolderEntityWH : public KnotHolderEntity { -public: - virtual Geom::Point knot_get() const; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); - -protected: - void set_internal(Geom::Point const &p, Geom::Point const &origin, unsigned int state); -}; - -/* handle for x/y adjustment */ -class RectKnotHolderEntityXY : public KnotHolderEntity { -public: - virtual Geom::Point knot_get() const; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); -}; - -Geom::Point -RectKnotHolderEntityRX::knot_get() const -{ - SPRect *rect = SP_RECT(item); - - return Geom::Point(rect->x.computed + rect->width.computed - rect->rx.computed, rect->y.computed); -} - -void -RectKnotHolderEntityRX::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, unsigned int state) -{ - SPRect *rect = SP_RECT(item); - - //In general we cannot just snap this radius to an arbitrary point, as we have only a single - //degree of freedom. For snapping to an arbitrary point we need two DOF. If we're going to snap - //the radius then we should have a constrained snap. snap_knot_position() is unconstrained - Geom::Point const s = snap_knot_position_constrained(p, Inkscape::Snapper::SnapConstraint(Geom::Point(rect->x.computed + rect->width.computed, rect->y.computed), Geom::Point(-1, 0)), state); - - if (state & GDK_CONTROL_MASK) { - gdouble temp = MIN(rect->height.computed, rect->width.computed) / 2.0; - rect->rx.computed = rect->ry.computed = CLAMP(rect->x.computed + rect->width.computed - s[Geom::X], 0.0, temp); - rect->rx._set = rect->ry._set = true; - - } else { - rect->rx.computed = CLAMP(rect->x.computed + rect->width.computed - s[Geom::X], 0.0, rect->width.computed / 2.0); - rect->rx._set = true; - } - - update_knot(); - - (static_cast(rect))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); -} - -void -RectKnotHolderEntityRX::knot_click(unsigned int state) -{ - SPRect *rect = SP_RECT(item); - - if (state & GDK_SHIFT_MASK) { - /* remove rounding from rectangle */ - rect->getRepr()->setAttribute("rx", NULL); - rect->getRepr()->setAttribute("ry", NULL); - } else if (state & GDK_CONTROL_MASK) { - /* Ctrl-click sets the vertical rounding to be the same as the horizontal */ - rect->getRepr()->setAttribute("ry", rect->getRepr()->attribute("rx")); - } - -} - -Geom::Point -RectKnotHolderEntityRY::knot_get() const -{ - SPRect *rect = SP_RECT(item); - - return Geom::Point(rect->x.computed + rect->width.computed, rect->y.computed + rect->ry.computed); -} - -void -RectKnotHolderEntityRY::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, unsigned int state) -{ - SPRect *rect = SP_RECT(item); - - //In general we cannot just snap this radius to an arbitrary point, as we have only a single - //degree of freedom. For snapping to an arbitrary point we need two DOF. If we're going to snap - //the radius then we should have a constrained snap. snap_knot_position() is unconstrained - Geom::Point const s = snap_knot_position_constrained(p, Inkscape::Snapper::SnapConstraint(Geom::Point(rect->x.computed + rect->width.computed, rect->y.computed), Geom::Point(0, 1)), state); - - if (state & GDK_CONTROL_MASK) { // When holding control then rx will be kept equal to ry, - // resulting in a perfect circle (and not an ellipse) - gdouble temp = MIN(rect->height.computed, rect->width.computed) / 2.0; - rect->rx.computed = rect->ry.computed = CLAMP(s[Geom::Y] - rect->y.computed, 0.0, temp); - rect->ry._set = rect->rx._set = true; - } else { - if (!rect->rx._set || rect->rx.computed == 0) { - rect->ry.computed = CLAMP(s[Geom::Y] - rect->y.computed, - 0.0, - MIN(rect->height.computed / 2.0, rect->width.computed / 2.0)); - } else { - rect->ry.computed = CLAMP(s[Geom::Y] - rect->y.computed, - 0.0, - rect->height.computed / 2.0); - } - - rect->ry._set = true; - } - - update_knot(); - - (static_cast(rect))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); -} - -void -RectKnotHolderEntityRY::knot_click(unsigned int state) -{ - SPRect *rect = SP_RECT(item); - - if (state & GDK_SHIFT_MASK) { - /* remove rounding */ - rect->getRepr()->setAttribute("rx", NULL); - rect->getRepr()->setAttribute("ry", NULL); - } else if (state & GDK_CONTROL_MASK) { - /* Ctrl-click sets the vertical rounding to be the same as the horizontal */ - rect->getRepr()->setAttribute("rx", rect->getRepr()->attribute("ry")); - } -} - -#define SGN(x) ((x)>0?1:((x)<0?-1:0)) - -static void sp_rect_clamp_radii(SPRect *rect) -{ - // clamp rounding radii so that they do not exceed width/height - if (2 * rect->rx.computed > rect->width.computed) { - rect->rx.computed = 0.5 * rect->width.computed; - rect->rx._set = true; - } - if (2 * rect->ry.computed > rect->height.computed) { - rect->ry.computed = 0.5 * rect->height.computed; - rect->ry._set = true; - } -} - -Geom::Point -RectKnotHolderEntityWH::knot_get() const -{ - SPRect *rect = SP_RECT(item); - - return Geom::Point(rect->x.computed + rect->width.computed, rect->y.computed + rect->height.computed); -} - -void -RectKnotHolderEntityWH::set_internal(Geom::Point const &p, Geom::Point const &origin, unsigned int state) -{ - SPRect *rect = SP_RECT(item); - - Geom::Point s = p; - - if (state & GDK_CONTROL_MASK) { - // original width/height when drag started - gdouble const w_orig = (origin[Geom::X] - rect->x.computed); - gdouble const h_orig = (origin[Geom::Y] - rect->y.computed); - - //original ratio - gdouble ratio = (w_orig / h_orig); - - // mouse displacement since drag started - gdouble minx = p[Geom::X] - origin[Geom::X]; - gdouble miny = p[Geom::Y] - origin[Geom::Y]; - - Geom::Point p_handle(rect->x.computed + rect->width.computed, rect->y.computed + rect->height.computed); - - if (fabs(minx) > fabs(miny)) { - // snap to horizontal or diagonal - if (minx != 0 && fabs(miny/minx) > 0.5 * 1/ratio && (SGN(minx) == SGN(miny))) { - // closer to the diagonal and in same-sign quarters, change both using ratio - s = snap_knot_position_constrained(p, Inkscape::Snapper::SnapConstraint(p_handle, Geom::Point(-ratio, -1)), state); - minx = s[Geom::X] - origin[Geom::X]; - miny = s[Geom::Y] - origin[Geom::Y]; - rect->height.computed = MAX(h_orig + minx / ratio, 0); - } else { - // closer to the horizontal, change only width, height is h_orig - s = snap_knot_position_constrained(p, Inkscape::Snapper::SnapConstraint(p_handle, Geom::Point(-1, 0)), state); - minx = s[Geom::X] - origin[Geom::X]; - miny = s[Geom::Y] - origin[Geom::Y]; - rect->height.computed = MAX(h_orig, 0); - } - rect->width.computed = MAX(w_orig + minx, 0); - - } else { - // snap to vertical or diagonal - if (miny != 0 && fabs(minx/miny) > 0.5 * ratio && (SGN(minx) == SGN(miny))) { - // closer to the diagonal and in same-sign quarters, change both using ratio - s = snap_knot_position_constrained(p, Inkscape::Snapper::SnapConstraint(p_handle, Geom::Point(-ratio, -1)), state); - minx = s[Geom::X] - origin[Geom::X]; - miny = s[Geom::Y] - origin[Geom::Y]; - rect->width.computed = MAX(w_orig + miny * ratio, 0); - } else { - // closer to the vertical, change only height, width is w_orig - s = snap_knot_position_constrained(p, Inkscape::Snapper::SnapConstraint(p_handle, Geom::Point(0, -1)), state); - minx = s[Geom::X] - origin[Geom::X]; - miny = s[Geom::Y] - origin[Geom::Y]; - rect->width.computed = MAX(w_orig, 0); - } - rect->height.computed = MAX(h_orig + miny, 0); - - } - - rect->width._set = rect->height._set = true; - - } else { - // move freely - s = snap_knot_position(p, state); - rect->width.computed = MAX(s[Geom::X] - rect->x.computed, 0); - rect->height.computed = MAX(s[Geom::Y] - rect->y.computed, 0); - rect->width._set = rect->height._set = true; - } - - sp_rect_clamp_radii(rect); - - (static_cast(rect))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); -} - -void -RectKnotHolderEntityWH::knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state) -{ - set_internal(p, origin, state); - update_knot(); -} - -Geom::Point -RectKnotHolderEntityXY::knot_get() const -{ - SPRect *rect = SP_RECT(item); - - return Geom::Point(rect->x.computed, rect->y.computed); -} - -void -RectKnotHolderEntityXY::knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state) -{ - SPRect *rect = SP_RECT(item); - - // opposite corner (unmoved) - gdouble opposite_x = (rect->x.computed + rect->width.computed); - gdouble opposite_y = (rect->y.computed + rect->height.computed); - - // original width/height when drag started - gdouble w_orig = opposite_x - origin[Geom::X]; - gdouble h_orig = opposite_y - origin[Geom::Y]; - - Geom::Point s = p; - Geom::Point p_handle(rect->x.computed, rect->y.computed); - - // mouse displacement since drag started - gdouble minx = p[Geom::X] - origin[Geom::X]; - gdouble miny = p[Geom::Y] - origin[Geom::Y]; - - if (state & GDK_CONTROL_MASK) { - //original ratio - gdouble ratio = (w_orig / h_orig); - - if (fabs(minx) > fabs(miny)) { - // snap to horizontal or diagonal - if (minx != 0 && fabs(miny/minx) > 0.5 * 1/ratio && (SGN(minx) == SGN(miny))) { - // closer to the diagonal and in same-sign quarters, change both using ratio - s = snap_knot_position_constrained(p, Inkscape::Snapper::SnapConstraint(p_handle, Geom::Point(-ratio, -1)), state); - minx = s[Geom::X] - origin[Geom::X]; - miny = s[Geom::Y] - origin[Geom::Y]; - rect->y.computed = MIN(origin[Geom::Y] + minx / ratio, opposite_y); - rect->height.computed = MAX(h_orig - minx / ratio, 0); - } else { - // closer to the horizontal, change only width, height is h_orig - s = snap_knot_position_constrained(p, Inkscape::Snapper::SnapConstraint(p_handle, Geom::Point(-1, 0)), state); - minx = s[Geom::X] - origin[Geom::X]; - miny = s[Geom::Y] - origin[Geom::Y]; - rect->y.computed = MIN(origin[Geom::Y], opposite_y); - rect->height.computed = MAX(h_orig, 0); - } - rect->x.computed = MIN(s[Geom::X], opposite_x); - rect->width.computed = MAX(w_orig - minx, 0); - } else { - // snap to vertical or diagonal - if (miny != 0 && fabs(minx/miny) > 0.5 *ratio && (SGN(minx) == SGN(miny))) { - // closer to the diagonal and in same-sign quarters, change both using ratio - s = snap_knot_position_constrained(p, Inkscape::Snapper::SnapConstraint(p_handle, Geom::Point(-ratio, -1)), state); - minx = s[Geom::X] - origin[Geom::X]; - miny = s[Geom::Y] - origin[Geom::Y]; - rect->x.computed = MIN(origin[Geom::X] + miny * ratio, opposite_x); - rect->width.computed = MAX(w_orig - miny * ratio, 0); - } else { - // closer to the vertical, change only height, width is w_orig - s = snap_knot_position_constrained(p, Inkscape::Snapper::SnapConstraint(p_handle, Geom::Point(0, -1)), state); - minx = s[Geom::X] - origin[Geom::X]; - miny = s[Geom::Y] - origin[Geom::Y]; - rect->x.computed = MIN(origin[Geom::X], opposite_x); - rect->width.computed = MAX(w_orig, 0); - } - rect->y.computed = MIN(s[Geom::Y], opposite_y); - rect->height.computed = MAX(h_orig - miny, 0); - } - - rect->width._set = rect->height._set = rect->x._set = rect->y._set = true; - - } else { - // move freely - s = snap_knot_position(p, state); - minx = s[Geom::X] - origin[Geom::X]; - miny = s[Geom::Y] - origin[Geom::Y]; - - rect->x.computed = MIN(s[Geom::X], opposite_x); - rect->width.computed = MAX(w_orig - minx, 0); - rect->y.computed = MIN(s[Geom::Y], opposite_y); - rect->height.computed = MAX(h_orig - miny, 0); - rect->width._set = rect->height._set = rect->x._set = rect->y._set = true; - } - - sp_rect_clamp_radii(rect); - - update_knot(); - - (static_cast(rect))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); -} - -RectKnotHolder::RectKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler) : - KnotHolder(desktop, item, relhandler) -{ - RectKnotHolderEntityRX *entity_rx = new RectKnotHolderEntityRX(); - RectKnotHolderEntityRY *entity_ry = new RectKnotHolderEntityRY(); - RectKnotHolderEntityWH *entity_wh = new RectKnotHolderEntityWH(); - RectKnotHolderEntityXY *entity_xy = new RectKnotHolderEntityXY(); - - entity_rx->create(desktop, item, this, Inkscape::CTRL_TYPE_ROTATE, - _("Adjust the horizontal rounding radius; with Ctrl " - "to make the vertical radius the same"), - SP_KNOT_SHAPE_CIRCLE, SP_KNOT_MODE_XOR); - - entity_ry->create(desktop, item, this, Inkscape::CTRL_TYPE_ROTATE, - _("Adjust the vertical rounding radius; with Ctrl " - "to make the horizontal radius the same"), - SP_KNOT_SHAPE_CIRCLE, SP_KNOT_MODE_XOR); - - entity_wh->create(desktop, item, this, Inkscape::CTRL_TYPE_SIZER, - _("Adjust the width and height of the rectangle; with Ctrl " - "to lock ratio or stretch in one dimension only"), - SP_KNOT_SHAPE_SQUARE, SP_KNOT_MODE_XOR); - - entity_xy->create(desktop, item, this, Inkscape::CTRL_TYPE_SIZER, - _("Adjust the width and height of the rectangle; with Ctrl " - "to lock ratio or stretch in one dimension only"), - SP_KNOT_SHAPE_SQUARE, SP_KNOT_MODE_XOR); - - entity.push_back(entity_rx); - entity.push_back(entity_ry); - entity.push_back(entity_wh); - entity.push_back(entity_xy); - - add_pattern_knotholder(); -} - -/* Box3D (= the new 3D box structure) */ - -class Box3DKnotHolderEntity : public KnotHolderEntity { -public: - virtual Geom::Point knot_get() const = 0; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state) = 0; - - Geom::Point knot_get_generic(SPItem *item, unsigned int knot_id) const; - void knot_set_generic(SPItem *item, unsigned int knot_id, Geom::Point const &p, unsigned int state); -}; - -Geom::Point -Box3DKnotHolderEntity::knot_get_generic(SPItem *item, unsigned int knot_id) const -{ - return box3d_get_corner_screen(SP_BOX3D(item), knot_id); -} - -void -Box3DKnotHolderEntity::knot_set_generic(SPItem *item, unsigned int knot_id, Geom::Point const &new_pos, unsigned int state) -{ - Geom::Point const s = snap_knot_position(new_pos, state); - - g_assert(item != NULL); - SPBox3D *box = SP_BOX3D(item); - Geom::Affine const i2dt (item->i2dt_affine ()); - - Box3D::Axis movement; - if ((knot_id < 4) != (state & GDK_SHIFT_MASK)) { - movement = Box3D::XY; - } else { - movement = Box3D::Z; - } - - box3d_set_corner (box, knot_id, s * i2dt, movement, (state & GDK_CONTROL_MASK)); - box3d_set_z_orders(box); - box3d_position_set(box); -} - -class Box3DKnotHolderEntity0 : public Box3DKnotHolderEntity { -public: - virtual Geom::Point knot_get() const; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); -}; - -class Box3DKnotHolderEntity1 : public Box3DKnotHolderEntity { -public: - virtual Geom::Point knot_get() const; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); -}; - -class Box3DKnotHolderEntity2 : public Box3DKnotHolderEntity { -public: - virtual Geom::Point knot_get() const; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); -}; - -class Box3DKnotHolderEntity3 : public Box3DKnotHolderEntity { -public: - virtual Geom::Point knot_get() const; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); -}; - -class Box3DKnotHolderEntity4 : public Box3DKnotHolderEntity { -public: - virtual Geom::Point knot_get() const; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); -}; - -class Box3DKnotHolderEntity5 : public Box3DKnotHolderEntity { -public: - virtual Geom::Point knot_get() const; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); -}; - -class Box3DKnotHolderEntity6 : public Box3DKnotHolderEntity { -public: - virtual Geom::Point knot_get() const; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); -}; - -class Box3DKnotHolderEntity7 : public Box3DKnotHolderEntity { -public: - virtual Geom::Point knot_get() const; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); -}; - -class Box3DKnotHolderEntityCenter : public KnotHolderEntity { -public: - virtual Geom::Point knot_get() const; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); -}; - -Geom::Point -Box3DKnotHolderEntity0::knot_get() const -{ - return knot_get_generic(item, 0); -} - -Geom::Point -Box3DKnotHolderEntity1::knot_get() const -{ - return knot_get_generic(item, 1); -} - -Geom::Point -Box3DKnotHolderEntity2::knot_get() const -{ - return knot_get_generic(item, 2); -} - -Geom::Point -Box3DKnotHolderEntity3::knot_get() const -{ - return knot_get_generic(item, 3); -} - -Geom::Point -Box3DKnotHolderEntity4::knot_get() const -{ - return knot_get_generic(item, 4); -} - -Geom::Point -Box3DKnotHolderEntity5::knot_get() const -{ - return knot_get_generic(item, 5); -} - -Geom::Point -Box3DKnotHolderEntity6::knot_get() const -{ - return knot_get_generic(item, 6); -} - -Geom::Point -Box3DKnotHolderEntity7::knot_get() const -{ - return knot_get_generic(item, 7); -} - -Geom::Point -Box3DKnotHolderEntityCenter::knot_get() const -{ - return box3d_get_center_screen(SP_BOX3D(item)); -} - -void -Box3DKnotHolderEntity0::knot_set(Geom::Point const &new_pos, Geom::Point const &/*origin*/, unsigned int state) -{ - knot_set_generic(item, 0, new_pos, state); -} - -void -Box3DKnotHolderEntity1::knot_set(Geom::Point const &new_pos, Geom::Point const &/*origin*/, unsigned int state) -{ - knot_set_generic(item, 1, new_pos, state); -} - -void -Box3DKnotHolderEntity2::knot_set(Geom::Point const &new_pos, Geom::Point const &/*origin*/, unsigned int state) -{ - knot_set_generic(item, 2, new_pos, state); -} - -void -Box3DKnotHolderEntity3::knot_set(Geom::Point const &new_pos, Geom::Point const &/*origin*/, unsigned int state) -{ - knot_set_generic(item, 3, new_pos, state); -} - -void -Box3DKnotHolderEntity4::knot_set(Geom::Point const &new_pos, Geom::Point const &/*origin*/, unsigned int state) -{ - knot_set_generic(item, 4, new_pos, state); -} - -void -Box3DKnotHolderEntity5::knot_set(Geom::Point const &new_pos, Geom::Point const &/*origin*/, unsigned int state) -{ - knot_set_generic(item, 5, new_pos, state); -} - -void -Box3DKnotHolderEntity6::knot_set(Geom::Point const &new_pos, Geom::Point const &/*origin*/, unsigned int state) -{ - knot_set_generic(item, 6, new_pos, state); -} - -void -Box3DKnotHolderEntity7::knot_set(Geom::Point const &new_pos, Geom::Point const &/*origin*/, unsigned int state) -{ - knot_set_generic(item, 7, new_pos, state); -} - -void -Box3DKnotHolderEntityCenter::knot_set(Geom::Point const &new_pos, Geom::Point const &origin, unsigned int state) -{ - Geom::Point const s = snap_knot_position(new_pos, state); - - SPBox3D *box = SP_BOX3D(item); - Geom::Affine const i2dt (item->i2dt_affine ()); - - box3d_set_center (SP_BOX3D(item), s * i2dt, origin * i2dt, !(state & GDK_SHIFT_MASK) ? Box3D::XY : Box3D::Z, - state & GDK_CONTROL_MASK); - - box3d_set_z_orders(box); - box3d_position_set(box); -} - -Box3DKnotHolder::Box3DKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler) : - KnotHolder(desktop, item, relhandler) -{ - Box3DKnotHolderEntity0 *entity_corner0 = new Box3DKnotHolderEntity0(); - Box3DKnotHolderEntity1 *entity_corner1 = new Box3DKnotHolderEntity1(); - Box3DKnotHolderEntity2 *entity_corner2 = new Box3DKnotHolderEntity2(); - Box3DKnotHolderEntity3 *entity_corner3 = new Box3DKnotHolderEntity3(); - Box3DKnotHolderEntity4 *entity_corner4 = new Box3DKnotHolderEntity4(); - Box3DKnotHolderEntity5 *entity_corner5 = new Box3DKnotHolderEntity5(); - Box3DKnotHolderEntity6 *entity_corner6 = new Box3DKnotHolderEntity6(); - Box3DKnotHolderEntity7 *entity_corner7 = new Box3DKnotHolderEntity7(); - Box3DKnotHolderEntityCenter *entity_center = new Box3DKnotHolderEntityCenter(); - - entity_corner0->create(desktop, item, this, Inkscape::CTRL_TYPE_SHAPER, - _("Resize box in X/Y direction; with Shift along the Z axis; " - "with Ctrl to constrain to the directions of edges or diagonals")); - - entity_corner1->create(desktop, item, this, Inkscape::CTRL_TYPE_SHAPER, - _("Resize box in X/Y direction; with Shift along the Z axis; " - "with Ctrl to constrain to the directions of edges or diagonals")); - - entity_corner2->create(desktop, item, this, Inkscape::CTRL_TYPE_SHAPER, - _("Resize box in X/Y direction; with Shift along the Z axis; " - "with Ctrl to constrain to the directions of edges or diagonals")); - - entity_corner3->create(desktop, item, this, Inkscape::CTRL_TYPE_SHAPER, - _("Resize box in X/Y direction; with Shift along the Z axis; " - "with Ctrl to constrain to the directions of edges or diagonals")); - - entity_corner4->create(desktop, item, this, Inkscape::CTRL_TYPE_SHAPER, - _("Resize box along the Z axis; with Shift in X/Y direction; " - "with Ctrl to constrain to the directions of edges or diagonals")); - - entity_corner5->create(desktop, item, this, Inkscape::CTRL_TYPE_SHAPER, - _("Resize box along the Z axis; with Shift in X/Y direction; " - "with Ctrl to constrain to the directions of edges or diagonals")); - - entity_corner6->create(desktop, item, this, Inkscape::CTRL_TYPE_SHAPER, - _("Resize box along the Z axis; with Shift in X/Y direction; " - "with Ctrl to constrain to the directions of edges or diagonals")); - - entity_corner7->create(desktop, item, this, Inkscape::CTRL_TYPE_SHAPER, - _("Resize box along the Z axis; with Shift in X/Y direction; " - "with Ctrl to constrain to the directions of edges or diagonals")); - - entity_center->create(desktop, item, this, Inkscape::CTRL_TYPE_POINT, - _("Move the box in perspective"), - SP_KNOT_SHAPE_CROSS); - - entity.push_back(entity_corner0); - entity.push_back(entity_corner1); - entity.push_back(entity_corner2); - entity.push_back(entity_corner3); - entity.push_back(entity_corner4); - entity.push_back(entity_corner5); - entity.push_back(entity_corner6); - entity.push_back(entity_corner7); - entity.push_back(entity_center); - - add_pattern_knotholder(); -} - -/* SPArc */ - -class ArcKnotHolderEntityStart : public KnotHolderEntity { -public: - virtual Geom::Point knot_get() const; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); - virtual void knot_click(unsigned int state); -}; - -class ArcKnotHolderEntityEnd : public KnotHolderEntity { -public: - virtual Geom::Point knot_get() const; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); - virtual void knot_click(unsigned int state); -}; - -class ArcKnotHolderEntityRX : public KnotHolderEntity { -public: - virtual Geom::Point knot_get() const; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); - virtual void knot_click(unsigned int state); -}; - -class ArcKnotHolderEntityRY : public KnotHolderEntity { -public: - virtual Geom::Point knot_get() const; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); - virtual void knot_click(unsigned int state); -}; - -/* - * return values: - * 1 : inside - * 0 : on the curves - * -1 : outside - */ -static gint -sp_genericellipse_side(SPGenericEllipse *ellipse, Geom::Point const &p) -{ - gdouble dx = (p[Geom::X] - ellipse->cx.computed) / ellipse->rx.computed; - gdouble dy = (p[Geom::Y] - ellipse->cy.computed) / ellipse->ry.computed; - - gdouble s = dx * dx + dy * dy; - if (s < 1.0) return 1; - if (s > 1.0) return -1; - return 0; -} - -void -ArcKnotHolderEntityStart::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, unsigned int state) -{ - int snaps = Inkscape::Preferences::get()->getInt("/options/rotationsnapsperpi/value", 12); - - SPGenericEllipse *arc = SP_GENERICELLIPSE(item); - - arc->setClosed(sp_genericellipse_side(arc, p) == -1); - - Geom::Point delta = p - Geom::Point(arc->cx.computed, arc->cy.computed); - Geom::Scale sc(arc->rx.computed, arc->ry.computed); - - arc->start = atan2(delta * sc.inverse()); - - if ((state & GDK_CONTROL_MASK) && snaps) { - arc->start = sp_round(arc->start, M_PI / snaps); - } - - arc->normalize(); - arc->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); -} - -Geom::Point -ArcKnotHolderEntityStart::knot_get() const -{ - SPGenericEllipse const *ge = SP_GENERICELLIPSE(item); - - return ge->getPointAtAngle(ge->start); -} - -void -ArcKnotHolderEntityStart::knot_click(unsigned int state) -{ - SPGenericEllipse *ge = SP_GENERICELLIPSE(item); - - if (state & GDK_SHIFT_MASK) { - ge->end = ge->start = 0; - (static_cast(ge))->updateRepr(); - } -} - -void -ArcKnotHolderEntityEnd::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, unsigned int state) -{ - int snaps = Inkscape::Preferences::get()->getInt("/options/rotationsnapsperpi/value", 12); - - SPGenericEllipse *arc = SP_GENERICELLIPSE(item); - - arc->setClosed(sp_genericellipse_side(arc, p) == -1); - - Geom::Point delta = p - Geom::Point(arc->cx.computed, arc->cy.computed); - Geom::Scale sc(arc->rx.computed, arc->ry.computed); - - arc->end = atan2(delta * sc.inverse()); - - if ((state & GDK_CONTROL_MASK) && snaps) { - arc->end = sp_round(arc->end, M_PI/snaps); - } - - arc->normalize(); - arc->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); -} - -Geom::Point -ArcKnotHolderEntityEnd::knot_get() const -{ - SPGenericEllipse const *ge = SP_GENERICELLIPSE(item); - - return ge->getPointAtAngle(ge->end); -} - - -void -ArcKnotHolderEntityEnd::knot_click(unsigned int state) -{ - SPGenericEllipse *ge = SP_GENERICELLIPSE(item); - - if (state & GDK_SHIFT_MASK) { - ge->end = ge->start = 0; - (static_cast(ge))->updateRepr(); - } -} - - -void -ArcKnotHolderEntityRX::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, unsigned int state) -{ - SPGenericEllipse *ge = SP_GENERICELLIPSE(item); - - Geom::Point const s = snap_knot_position(p, state); - - ge->rx.computed = fabs( ge->cx.computed - s[Geom::X] ); - - if ( state & GDK_CONTROL_MASK ) { - ge->ry.computed = ge->rx.computed; - } - - (static_cast(item))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); -} - -Geom::Point -ArcKnotHolderEntityRX::knot_get() const -{ - SPGenericEllipse const *ge = SP_GENERICELLIPSE(item); - - return (Geom::Point(ge->cx.computed, ge->cy.computed) - Geom::Point(ge->rx.computed, 0)); -} - -void -ArcKnotHolderEntityRX::knot_click(unsigned int state) -{ - SPGenericEllipse *ge = SP_GENERICELLIPSE(item); - - if (state & GDK_CONTROL_MASK) { - ge->ry.computed = ge->rx.computed; - (static_cast(ge))->updateRepr(); - } -} - -void -ArcKnotHolderEntityRY::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, unsigned int state) -{ - SPGenericEllipse *ge = SP_GENERICELLIPSE(item); - - Geom::Point const s = snap_knot_position(p, state); - - ge->ry.computed = fabs( ge->cy.computed - s[Geom::Y] ); - - if ( state & GDK_CONTROL_MASK ) { - ge->rx.computed = ge->ry.computed; - } - - (static_cast(item))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); -} - -Geom::Point -ArcKnotHolderEntityRY::knot_get() const -{ - SPGenericEllipse const *ge = SP_GENERICELLIPSE(item); - - return (Geom::Point(ge->cx.computed, ge->cy.computed) - Geom::Point(0, ge->ry.computed)); -} - -void -ArcKnotHolderEntityRY::knot_click(unsigned int state) -{ - SPGenericEllipse *ge = SP_GENERICELLIPSE(item); - - if (state & GDK_CONTROL_MASK) { - ge->rx.computed = ge->ry.computed; - (static_cast(ge))->updateRepr(); - } -} - -ArcKnotHolder::ArcKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler) : - KnotHolder(desktop, item, relhandler) -{ - ArcKnotHolderEntityRX *entity_rx = new ArcKnotHolderEntityRX(); - ArcKnotHolderEntityRY *entity_ry = new ArcKnotHolderEntityRY(); - ArcKnotHolderEntityStart *entity_start = new ArcKnotHolderEntityStart(); - ArcKnotHolderEntityEnd *entity_end = new ArcKnotHolderEntityEnd(); - - entity_rx->create(desktop, item, this, Inkscape::CTRL_TYPE_SIZER, - _("Adjust ellipse width, with Ctrl to make circle"), - SP_KNOT_SHAPE_SQUARE, SP_KNOT_MODE_XOR); - - entity_ry->create(desktop, item, this, Inkscape::CTRL_TYPE_SIZER, - _("Adjust ellipse height, with Ctrl to make circle"), - SP_KNOT_SHAPE_SQUARE, SP_KNOT_MODE_XOR); - - entity_start->create(desktop, item, this, Inkscape::CTRL_TYPE_ROTATE, - _("Position the start point of the arc or segment; with Ctrl " - "to snap angle; drag inside the ellipse for arc, outside for segment"), - SP_KNOT_SHAPE_CIRCLE, SP_KNOT_MODE_XOR); - - entity_end->create(desktop, item, this, Inkscape::CTRL_TYPE_ROTATE, - _("Position the end point of the arc or segment; with Ctrl to snap angle; " - "drag inside the ellipse for arc, outside for segment"), - SP_KNOT_SHAPE_CIRCLE, SP_KNOT_MODE_XOR); - - entity.push_back(entity_rx); - entity.push_back(entity_ry); - entity.push_back(entity_start); - entity.push_back(entity_end); - - add_pattern_knotholder(); -} - -/* SPStar */ - -class StarKnotHolderEntity1 : public KnotHolderEntity { -public: - virtual Geom::Point knot_get() const; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); - virtual void knot_click(unsigned int state); -}; - -class StarKnotHolderEntity2 : public KnotHolderEntity { -public: - virtual Geom::Point knot_get() const; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); - virtual void knot_click(unsigned int state); -}; - -void -StarKnotHolderEntity1::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, unsigned int state) -{ - SPStar *star = SP_STAR(item); - - Geom::Point const s = snap_knot_position(p, state); - - Geom::Point d = s - star->center; - - double arg1 = atan2(d); - double darg1 = arg1 - star->arg[0]; - - if (state & GDK_MOD1_MASK) { - star->randomized = darg1/(star->arg[0] - star->arg[1]); - } else if (state & GDK_SHIFT_MASK) { - star->rounded = darg1/(star->arg[0] - star->arg[1]); - } else if (state & GDK_CONTROL_MASK) { - star->r[0] = L2(d); - } else { - star->r[0] = L2(d); - star->arg[0] = arg1; - star->arg[1] += darg1; - } - (static_cast(star))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); -} - -void -StarKnotHolderEntity2::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, unsigned int state) -{ - SPStar *star = SP_STAR(item); - - Geom::Point const s = snap_knot_position(p, state); - - if (star->flatsided == false) { - Geom::Point d = s - star->center; - - double arg1 = atan2(d); - double darg1 = arg1 - star->arg[1]; - - if (state & GDK_MOD1_MASK) { - star->randomized = darg1/(star->arg[0] - star->arg[1]); - } else if (state & GDK_SHIFT_MASK) { - star->rounded = fabs(darg1/(star->arg[0] - star->arg[1])); - } else if (state & GDK_CONTROL_MASK) { - star->r[1] = L2(d); - star->arg[1] = star->arg[0] + M_PI / star->sides; - } - else { - star->r[1] = L2(d); - star->arg[1] = atan2(d); - } - (static_cast(star))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - } -} - -Geom::Point -StarKnotHolderEntity1::knot_get() const -{ - g_assert(item != NULL); - - SPStar const *star = SP_STAR(item); - - return sp_star_get_xy(star, SP_STAR_POINT_KNOT1, 0); - -} - -Geom::Point -StarKnotHolderEntity2::knot_get() const -{ - g_assert(item != NULL); - - SPStar const *star = SP_STAR(item); - - return sp_star_get_xy(star, SP_STAR_POINT_KNOT2, 0); -} - -static void -sp_star_knot_click(SPItem *item, unsigned int state) -{ - SPStar *star = SP_STAR(item); - - if (state & GDK_MOD1_MASK) { - star->randomized = 0; - (static_cast(star))->updateRepr(); - } else if (state & GDK_SHIFT_MASK) { - star->rounded = 0; - (static_cast(star))->updateRepr(); - } else if (state & GDK_CONTROL_MASK) { - star->arg[1] = star->arg[0] + M_PI / star->sides; - (static_cast(star))->updateRepr(); - } -} - -void -StarKnotHolderEntity1::knot_click(unsigned int state) -{ - sp_star_knot_click(item, state); -} - -void -StarKnotHolderEntity2::knot_click(unsigned int state) -{ - sp_star_knot_click(item, state); -} - -StarKnotHolder::StarKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler) : - KnotHolder(desktop, item, relhandler) -{ - SPStar *star = SP_STAR(item); - - StarKnotHolderEntity1 *entity1 = new StarKnotHolderEntity1(); - entity1->create(desktop, item, this, Inkscape::CTRL_TYPE_SHAPER, - _("Adjust the tip radius of the star or polygon; " - "with Shift to round; with Alt to randomize")); - - entity.push_back(entity1); - - if (star->flatsided == false) { - StarKnotHolderEntity2 *entity2 = new StarKnotHolderEntity2(); - entity2->create(desktop, item, this, Inkscape::CTRL_TYPE_SHAPER, - _("Adjust the base radius of the star; with Ctrl to keep star rays " - "radial (no skew); with Shift to round; with Alt to randomize")); - entity.push_back(entity2); - } - - add_pattern_knotholder(); -} - -/* SPSpiral */ - -class SpiralKnotHolderEntityInner : public KnotHolderEntity { -public: - virtual Geom::Point knot_get() const; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); - virtual void knot_click(unsigned int state); -}; - -class SpiralKnotHolderEntityOuter : public KnotHolderEntity { -public: - virtual Geom::Point knot_get() const; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); -}; - - -/* - * set attributes via inner (t=t0) knot point: - * [default] increase/decrease inner point - * [shift] increase/decrease inner and outer arg synchronizely - * [control] constrain inner arg to round per PI/4 - */ -void -SpiralKnotHolderEntityInner::knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - int snaps = prefs->getInt("/options/rotationsnapsperpi/value", 12); - - SPSpiral *spiral = SP_SPIRAL(item); - - gdouble dx = p[Geom::X] - spiral->cx; - gdouble dy = p[Geom::Y] - spiral->cy; - - gdouble moved_y = p[Geom::Y] - origin[Geom::Y]; - - if (state & GDK_MOD1_MASK) { - // adjust divergence by vertical drag, relative to rad - if (spiral->rad > 0) { - double exp_delta = 0.1*moved_y/(spiral->rad); // arbitrary multiplier to slow it down - spiral->exp += exp_delta; - if (spiral->exp < 1e-3) - spiral->exp = 1e-3; - } - } else { - // roll/unroll from inside - gdouble arg_t0; - spiral->getPolar(spiral->t0, NULL, &arg_t0); - - gdouble arg_tmp = atan2(dy, dx) - arg_t0; - gdouble arg_t0_new = arg_tmp - floor((arg_tmp+M_PI)/(2.0*M_PI))*2.0*M_PI + arg_t0; - spiral->t0 = (arg_t0_new - spiral->arg) / (2.0*M_PI*spiral->revo); - - /* round inner arg per PI/snaps, if CTRL is pressed */ - if ( ( state & GDK_CONTROL_MASK ) - && ( fabs(spiral->revo) > SP_EPSILON_2 ) - && ( snaps != 0 ) ) { - gdouble arg = 2.0*M_PI*spiral->revo*spiral->t0 + spiral->arg; - spiral->t0 = (sp_round(arg, M_PI/snaps) - spiral->arg)/(2.0*M_PI*spiral->revo); - } - - spiral->t0 = CLAMP(spiral->t0, 0.0, 0.999); - } - - (static_cast(spiral))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); -} - -/* - * set attributes via outer (t=1) knot point: - * [default] increase/decrease revolution factor - * [control] constrain inner arg to round per PI/4 - */ -void -SpiralKnotHolderEntityOuter::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, unsigned int state) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - int snaps = prefs->getInt("/options/rotationsnapsperpi/value", 12); - - SPSpiral *spiral = SP_SPIRAL(item); - - gdouble dx = p[Geom::X] - spiral->cx; - gdouble dy = p[Geom::Y] - spiral->cy; - - if (state & GDK_SHIFT_MASK) { // rotate without roll/unroll - spiral->arg = atan2(dy, dx) - 2.0*M_PI*spiral->revo; - if (!(state & GDK_MOD1_MASK)) { - // if alt not pressed, change also rad; otherwise it is locked - spiral->rad = MAX(hypot(dx, dy), 0.001); - } - if ( ( state & GDK_CONTROL_MASK ) - && snaps ) { - spiral->arg = sp_round(spiral->arg, M_PI/snaps); - } - } else { // roll/unroll - // arg of the spiral outer end - double arg_1; - spiral->getPolar(1, NULL, &arg_1); - - // its fractional part after the whole turns are subtracted - double arg_r = arg_1 - sp_round(arg_1, 2.0*M_PI); - - // arg of the mouse point relative to spiral center - double mouse_angle = atan2(dy, dx); - if (mouse_angle < 0) - mouse_angle += 2*M_PI; - - // snap if ctrl - if ( ( state & GDK_CONTROL_MASK ) && snaps ) { - mouse_angle = sp_round(mouse_angle, M_PI/snaps); - } - - // by how much we want to rotate the outer point - double diff = mouse_angle - arg_r; - if (diff > M_PI) - diff -= 2*M_PI; - else if (diff < -M_PI) - diff += 2*M_PI; - - // calculate the new rad; - // the value of t corresponding to the angle arg_1 + diff: - double t_temp = ((arg_1 + diff) - spiral->arg)/(2*M_PI*spiral->revo); - // the rad at that t: - double rad_new = 0; - if (t_temp > spiral->t0) - spiral->getPolar(t_temp, &rad_new, NULL); - - // change the revo (converting diff from radians to the number of turns) - spiral->revo += diff/(2*M_PI); - if (spiral->revo < 1e-3) - spiral->revo = 1e-3; - - // if alt not pressed and the values are sane, change the rad - if (!(state & GDK_MOD1_MASK) && rad_new > 1e-3 && rad_new/spiral->rad < 2) { - // adjust t0 too so that the inner point stays unmoved - double r0; - spiral->getPolar(spiral->t0, &r0, NULL); - spiral->rad = rad_new; - spiral->t0 = pow(r0 / spiral->rad, 1.0/spiral->exp); - } - if (!IS_FINITE(spiral->t0)) spiral->t0 = 0.0; - spiral->t0 = CLAMP(spiral->t0, 0.0, 0.999); - } - - (static_cast(spiral))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); -} - -Geom::Point -SpiralKnotHolderEntityInner::knot_get() const -{ - SPSpiral const *spiral = SP_SPIRAL(item); - - return spiral->getXY(spiral->t0); -} - -Geom::Point -SpiralKnotHolderEntityOuter::knot_get() const -{ - SPSpiral const *spiral = SP_SPIRAL(item); - - return spiral->getXY(1.0); -} - -void -SpiralKnotHolderEntityInner::knot_click(unsigned int state) -{ - SPSpiral *spiral = SP_SPIRAL(item); - - if (state & GDK_MOD1_MASK) { - spiral->exp = 1; - (static_cast(spiral))->updateRepr(); - } else if (state & GDK_SHIFT_MASK) { - spiral->t0 = 0; - (static_cast(spiral))->updateRepr(); - } -} - -SpiralKnotHolder::SpiralKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler) : - KnotHolder(desktop, item, relhandler) -{ - SpiralKnotHolderEntityInner *entity_inner = new SpiralKnotHolderEntityInner(); - SpiralKnotHolderEntityOuter *entity_outer = new SpiralKnotHolderEntityOuter(); - - entity_inner->create(desktop, item, this, Inkscape::CTRL_TYPE_SHAPER, - _("Roll/unroll the spiral from inside; with Ctrl to snap angle; " - "with Alt to converge/diverge")); - - entity_outer->create(desktop, item, this, Inkscape::CTRL_TYPE_SHAPER, - _("Roll/unroll the spiral from outside; with Ctrl to snap angle; " - "with Shift to scale/rotate; with Alt to lock radius")); - - entity.push_back(entity_inner); - entity.push_back(entity_outer); - - add_pattern_knotholder(); -} - -/* SPOffset */ - -class OffsetKnotHolderEntity : public KnotHolderEntity { -public: - virtual Geom::Point knot_get() const; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); -}; - -void -OffsetKnotHolderEntity::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, unsigned int /*state*/) -{ - SPOffset *offset = SP_OFFSET(item); - - offset->rad = sp_offset_distance_to_original(offset, p); - offset->knot = p; - offset->knotSet = true; - - (static_cast(offset))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); -} - - -Geom::Point -OffsetKnotHolderEntity::knot_get() const -{ - SPOffset const *offset = SP_OFFSET(item); - - Geom::Point np; - sp_offset_top_point(offset,&np); - return np; -} - -OffsetKnotHolder::OffsetKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler) : - KnotHolder(desktop, item, relhandler) -{ - OffsetKnotHolderEntity *entity_offset = new OffsetKnotHolderEntity(); - entity_offset->create(desktop, item, this, Inkscape::CTRL_TYPE_SHAPER, - _("Adjust the offset distance")); - entity.push_back(entity_offset); - - add_pattern_knotholder(); -} - -// TODO: this is derived from RectKnotHolderEntityWH because it used the same static function -// set_internal as the latter before KnotHolderEntity was C++ified. Check whether this also makes -// sense logically. -class FlowtextKnotHolderEntity : public RectKnotHolderEntityWH { -public: - virtual Geom::Point knot_get() const; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); -}; - -Geom::Point -FlowtextKnotHolderEntity::knot_get() const -{ - SPRect const *rect = SP_RECT(item); - - return Geom::Point(rect->x.computed + rect->width.computed, rect->y.computed + rect->height.computed); -} - -void -FlowtextKnotHolderEntity::knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state) -{ - set_internal(p, origin, state); -} - -FlowtextKnotHolder::FlowtextKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler) : - KnotHolder(desktop, item, relhandler) -{ - g_assert(item != NULL); - - FlowtextKnotHolderEntity *entity_flowtext = new FlowtextKnotHolderEntity(); - entity_flowtext->create(desktop, item, this, Inkscape::CTRL_TYPE_SHAPER, - _("Drag to resize the flowed text frame")); - entity.push_back(entity_flowtext); -} - -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/object-edit.h b/src/object-edit.h deleted file mode 100644 index ba59e46cd..000000000 --- a/src/object-edit.h +++ /dev/null @@ -1,83 +0,0 @@ -#ifndef OBJECT_EDIT_H_SEEN -#define OBJECT_EDIT_H_SEEN - -/* - * Node editing extension to objects - * - * Authors: - * Lauris Kaplinski - * Mitsuru Oka - * Jon A. Cruz - * - * Licensed under GNU GPL - */ - -#include "knotholder.h" - -namespace Inkscape -{ - -KnotHolder *createKnotHolder(SPItem *item, SPDesktop *desktop); - -} - -class RectKnotHolder : public KnotHolder { -public: - RectKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler); - virtual ~RectKnotHolder() {}; -}; - -class Box3DKnotHolder : public KnotHolder { -public: - Box3DKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler); - virtual ~Box3DKnotHolder() {}; -}; - -class ArcKnotHolder : public KnotHolder { -public: - ArcKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler); - virtual ~ArcKnotHolder() {}; -}; - -class StarKnotHolder : public KnotHolder { -public: - StarKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler); - virtual ~StarKnotHolder() {}; -}; - -class SpiralKnotHolder : public KnotHolder { -public: - SpiralKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler); - virtual ~SpiralKnotHolder() {}; -}; - -class OffsetKnotHolder : public KnotHolder { -public: - OffsetKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler); - virtual ~OffsetKnotHolder() {}; -}; - -class FlowtextKnotHolder : public KnotHolder { -public: - FlowtextKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler); - virtual ~FlowtextKnotHolder() {}; -}; - -class MiscKnotHolder : public KnotHolder { -public: - MiscKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler); - virtual ~MiscKnotHolder() {}; -}; - -#endif // OBJECT_EDIT_H_SEEN - -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index b87bc421f..b27d591b3 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -37,7 +37,7 @@ SPCycleType SP_CYCLING = SP_CYCLE_FOCUS; #include "dir-util.h" #include "layer-model.h" #include "selection.h" -#include "tools-switch.h" +#include "ui/tools-switch.h" #include "desktop-handles.h" #include "message-stack.h" #include "sp-item-transform.h" @@ -112,7 +112,7 @@ SPCycleType SP_CYCLING = SP_CYCLE_FOCUS; #include "sp-item-group.h" // For clippath editing -#include "tools-switch.h" +#include "ui/tools-switch.h" #include "ui/tools/node-tool.h" #include "ui/clipboard.h" diff --git a/src/shape-editor.cpp b/src/shape-editor.cpp deleted file mode 100644 index 7915fe533..000000000 --- a/src/shape-editor.cpp +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Inkscape::ShapeEditor - * - * Authors: - * bulia byak - * Krzysztof KosiƄski - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include - -#include "desktop-handles.h" -#include "document.h" -#include "gc-anchored.h" -#include "knotholder.h" -#include "object-edit.h" -#include "sp-item.h" -#include "sp-object.h" -#include "shape-editor.h" -#include "xml/node-event-vector.h" - -using Inkscape::createKnotHolder; - -bool ShapeEditor::_blockSetItem = false; - -ShapeEditor::ShapeEditor(SPDesktop *dt) { - this->desktop = dt; - this->knotholder = NULL; - this->knotholder_listener_attached_for = NULL; -} - -ShapeEditor::~ShapeEditor() { - unset_item(); -} - -void ShapeEditor::unset_item(bool keep_knotholder) { - if (this->knotholder) { - Inkscape::XML::Node *old_repr = this->knotholder->repr; - if (old_repr && old_repr == knotholder_listener_attached_for) { - sp_repr_remove_listener_by_data(old_repr, this); - Inkscape::GC::release(old_repr); - knotholder_listener_attached_for = NULL; - } - - if (!keep_knotholder) { - delete this->knotholder; - this->knotholder = NULL; - } - } -} - -bool ShapeEditor::has_knotholder() { - return this->knotholder != NULL; -} - -void ShapeEditor::update_knotholder() { - if (this->knotholder) - this->knotholder->update_knots(); -} - -bool ShapeEditor::has_local_change() { - return (this->knotholder && this->knotholder->local_change != 0); -} - -void ShapeEditor::decrement_local_change() { - if (this->knotholder) { - this->knotholder->local_change = FALSE; - } -} - -const SPItem *ShapeEditor::get_item() { - const SPItem *item = NULL; - if (this->has_knotholder()) { - item = this->knotholder->getItem(); - } - return item; -} - -void ShapeEditor::event_attr_changed(Inkscape::XML::Node *, gchar const *name, gchar const *, gchar const *, bool, void *data) -{ - g_assert(data); - ShapeEditor *sh = static_cast(data); - bool changed_kh = false; - - if (sh->has_knotholder()) - { - changed_kh = !sh->has_local_change(); - sh->decrement_local_change(); - if (changed_kh) { - // this can happen if an LPEItem's knotholder handle was dragged, in which case we want - // to keep the knotholder; in all other cases (e.g., if the LPE itself changes) we delete it - sh->reset_item(!strcmp(name, "d")); - } - } -} - -static Inkscape::XML::NodeEventVector shapeeditor_repr_events = { - NULL, /* child_added */ - NULL, /* child_removed */ - ShapeEditor::event_attr_changed, - NULL, /* content_changed */ - NULL /* order_changed */ -}; - - -void ShapeEditor::set_item(SPItem *item, bool keep_knotholder) { - if (_blockSetItem) { - return; - } - - // this happens (and should only happen) when for an LPEItem having both knotholder and - // nodepath the knotholder is adapted; in this case we don't want to delete the knotholder - // since this freezes the handles - unset_item(keep_knotholder); - - if (item) { - Inkscape::XML::Node *repr; - if (!this->knotholder) { - // only recreate knotholder if none is present - this->knotholder = createKnotHolder(item, desktop); - } - if (this->knotholder) { - this->knotholder->update_knots(); - // setting new listener - repr = this->knotholder->repr; - if (repr != knotholder_listener_attached_for) { - Inkscape::GC::anchor(repr); - sp_repr_add_listener(repr, &shapeeditor_repr_events, this); - knotholder_listener_attached_for = repr; - } - } - } -} - - -/** FIXME: This thing is only called when the item needs to be updated in response to repr change. - Why not make a reload function in KnotHolder? */ -void ShapeEditor::reset_item(bool keep_knotholder) -{ - if (knotholder) { - SPObject *obj = sp_desktop_document(desktop)->getObjectByRepr(knotholder_listener_attached_for); /// note that it is not certain that this is an SPItem; it could be a LivePathEffectObject. - set_item(SP_ITEM(obj), keep_knotholder); - } -} - -/** - * Returns true if this ShapeEditor has a knot above which the mouse currently hovers. - */ -bool ShapeEditor::knot_mouseover() const { - if (this->knotholder) { - return knotholder->knot_mouseover(); - } - - return false; -} - -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/shape-editor.h b/src/shape-editor.h deleted file mode 100644 index d2611b111..000000000 --- a/src/shape-editor.h +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef SEEN_SHAPE_EDITOR_H -#define SEEN_SHAPE_EDITOR_H - -/* - * Inkscape::ShapeEditor - * - * This is a container class which contains a knotholder for shapes. - * It is attached to a single item. - * - * Authors: - * bulia byak - * - */ - -namespace Inkscape { namespace XML { class Node; } } - -class KnotHolder; -class LivePathEffectObject; -class SPDesktop; -class SPItem; - -class ShapeEditor { -public: - - ShapeEditor(SPDesktop *desktop); - ~ShapeEditor(); - - void set_item(SPItem *item, bool keep_knotholder = false); - void unset_item(bool keep_knotholder = false); - - void update_knotholder(); //((deprecated)) - - bool has_local_change(); - void decrement_local_change(); - - bool knot_mouseover() const; - - static void blockSetItem(bool b) { _blockSetItem = b; } // kludge - - static void event_attr_changed(Inkscape::XML::Node * /*repr*/, char const *name, char const * /*old_value*/, - char const * /*new_value*/, bool /*is_interactive*/, void *data); -private: - bool has_knotholder(); - void reset_item (bool keep_knotholder = true); - const SPItem *get_item(); - - static bool _blockSetItem; - - SPDesktop *desktop; - KnotHolder *knotholder; - Inkscape::XML::Node *knotholder_listener_attached_for; -}; - -#endif // SEEN_SHAPE_EDITOR_H - - -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : - diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index f012d1df7..a2a935951 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -36,14 +36,14 @@ #include "message-stack.h" #include "inkscape.h" #include "desktop.h" -#include "shape-editor.h" +#include "ui/shape-editor.h" #include "sp-ellipse.h" #include "display/curve.h" #include "svg/svg.h" #include <2geom/pathvector.h> #include "sp-clippath.h" #include "sp-mask.h" -#include "tools-switch.h" +#include "ui/tools-switch.h" #include "ui/tools/node-tool.h" #include "ui/tools/tool-base.h" diff --git a/src/tool-factory.h b/src/tool-factory.h deleted file mode 100644 index 726706732..000000000 --- a/src/tool-factory.h +++ /dev/null @@ -1,40 +0,0 @@ -/** @file - * Factory for ToolBase tree - *//* - * Authors: - * Markus Engel - * - * Copyright (C) 2013 Authors - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#ifndef TOOL_FACTORY_SEEN -#define TOOL_FACTORY_SEEN - -#include "factory.h" - -namespace Inkscape { -namespace UI { -namespace Tools { - -class ToolBase; - -} -} -} - -typedef Singleton< Factory > ToolFactory; - - -#endif - -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/tools-switch.cpp b/src/tools-switch.cpp deleted file mode 100644 index fe9d32f43..000000000 --- a/src/tools-switch.cpp +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Utility functions for switching tools (= contexts) - * - * Authors: - * bulia byak - * Josh Andler - * - * Copyright (C) 2003-2007 authors - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include -#include - -#include "inkscape-private.h" -#include "desktop.h" -#include "desktop-handles.h" -#include - -#include - -#include "ui/tools/select-tool.h" -#include "ui/tools/node-tool.h" -#include "ui/tools/tweak-tool.h" -#include "ui/tools/spray-tool.h" -#include "sp-path.h" -#include "ui/tools/rect-tool.h" -#include "sp-rect.h" -#include "ui/tools/box3d-tool.h" -#include "box3d.h" -#include "ui/tools/arc-tool.h" -#include "sp-ellipse.h" -#include "ui/tools/tweak-tool.h" -#include "sp-star.h" -#include "ui/tools/spiral-tool.h" -#include "sp-spiral.h" -#include "ui/tools/calligraphic-tool.h" -#include "ui/tools/eraser-tool.h" -#include "ui/tools/pen-tool.h" -#include "ui/tools/pencil-tool.h" -#include "ui/tools/lpe-tool.h" -#include "ui/tools/text-tool.h" -#include "sp-text.h" -#include "sp-flowtext.h" -#include "ui/tools/gradient-tool.h" -#include "ui/tools/mesh-tool.h" -#include "ui/tools/zoom-tool.h" -#include "ui/tools/measure-tool.h" -#include "ui/tools/dropper-tool.h" -#include "ui/tools/connector-tool.h" -#include "ui/tools/flood-tool.h" -#include "sp-offset.h" -#include "message-context.h" - -#include "tools-switch.h" - -static char const *const tool_names[] = { - NULL, - "/tools/select", - "/tools/nodes", - "/tools/tweak", - "/tools/spray", - "/tools/shapes/rect", - "/tools/shapes/3dbox", - "/tools/shapes/arc", - "/tools/shapes/star", - "/tools/shapes/spiral", - "/tools/freehand/pencil", - "/tools/freehand/pen", - "/tools/calligraphic", - "/tools/text", - "/tools/gradient", - "/tools/mesh", - "/tools/zoom", - "/tools/measure", - "/tools/dropper", - "/tools/connector", - "/tools/paintbucket", - "/tools/eraser", - "/tools/lpetool", - NULL -}; -static char const *const tool_msg[] = { - NULL, - N_("Click to Select and Transform objects, Drag to select many objects."), - N_("Modify selected path points (nodes) directly."), - N_("To tweak a path by pushing, select it and drag over it."), - N_("Drag, click or click and scroll to spray the selected objects."), - N_("Drag to create a rectangle. Drag controls to round corners and resize. Click to select."), - N_("Drag to create a 3D box. Drag controls to resize in perspective. Click to select (with Ctrl+Alt for single faces)."), - N_("Drag to create an ellipse. Drag controls to make an arc or segment. Click to select."), - N_("Drag to create a star. Drag controls to edit the star shape. Click to select."), - N_("Drag to create a spiral. Drag controls to edit the spiral shape. Click to select."), - N_("Drag to create a freehand line. Shift appends to selected path, Alt activates sketch mode."), - N_("Click or click and drag to start a path; with Shift to append to selected path. Ctrl+click to create single dots (straight line modes only)."), - N_("Drag to draw a calligraphic stroke; with Ctrl to track a guide path. Arrow keys adjust width (left/right) and angle (up/down)."), - N_("Click to select or create text, drag to create flowed text; then type."), - N_("Drag or double click to create a gradient on selected objects, drag handles to adjust gradients."), - N_("Drag or double click to create a mesh on selected objects, drag handles to adjust meshes."), - N_("Click or drag around an area to zoom in, Shift+click to zoom out."), - N_("Drag to measure the dimensions of objects."), - N_("Click to set fill, Shift+click to set stroke; drag to average color in area; with Alt to pick inverse color; Ctrl+C to copy the color under mouse to clipboard"), - N_("Click and drag between shapes to create a connector."), - N_("Click to paint a bounded area, Shift+click to union the new fill with the current selection, Ctrl+click to change the clicked object's fill and stroke to the current setting."), - N_("Drag to erase."), - N_("Choose a subtool from the toolbar"), -}; - -static int -tools_prefpath2num(char const *id) -{ - int i = 1; - while (tool_names[i]) { - if (strcmp(tool_names[i], id) == 0) - return i; - else i++; - } - g_assert( 0 == TOOLS_INVALID ); - return 0; //nothing found -} - -int -tools_isactive(SPDesktop *dt, unsigned num) -{ - g_assert( num < G_N_ELEMENTS(tool_names) ); - if (SP_IS_EVENT_CONTEXT(dt->event_context)) - return dt->event_context->pref_observer->observed_path == tool_names[num]; - else return FALSE; -} - -int -tools_active(SPDesktop *dt) -{ - return tools_prefpath2num(dt->event_context->pref_observer->observed_path.data()); -} - -void -tools_switch(SPDesktop *dt, int num) -{ - dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, gettext( tool_msg[num] ) ); - if (dt) { - // This event may change the above message - dt->_tool_changed.emit(num); - } - - dt->set_event_context2(tool_names[num]); - /* fixme: This is really ugly hack. We should bind and unbind class methods */ - /* First 4 tools use guides, first is undefined but we don't care */ - dt->activate_guides(num < 5); - inkscape_eventcontext_set(dt->getEventContext()); -} - -void tools_switch_by_item(SPDesktop *dt, SPItem *item, Geom::Point const p) -{ - if (SP_IS_RECT(item)) { - tools_switch(dt, TOOLS_SHAPES_RECT); - } else if (SP_IS_BOX3D(item)) { - tools_switch(dt, TOOLS_SHAPES_3DBOX); - } else if (SP_IS_GENERICELLIPSE(item)) { - tools_switch(dt, TOOLS_SHAPES_ARC); - } else if (SP_IS_STAR(item)) { - tools_switch(dt, TOOLS_SHAPES_STAR); - } else if (SP_IS_SPIRAL(item)) { - tools_switch(dt, TOOLS_SHAPES_SPIRAL); - } else if (SP_IS_PATH(item)) { - if (Inkscape::UI::Tools::cc_item_is_connector(item)) { - tools_switch(dt, TOOLS_CONNECTOR); - } - else { - tools_switch(dt, TOOLS_NODES); - } - } else if (SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item)) { - tools_switch(dt, TOOLS_TEXT); - sp_text_context_place_cursor_at (SP_TEXT_CONTEXT(dt->event_context), SP_OBJECT(item), p); - } else if (SP_IS_OFFSET(item)) { - tools_switch(dt, TOOLS_NODES); - } -} - -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/tools-switch.h b/src/tools-switch.h deleted file mode 100644 index 280837e87..000000000 --- a/src/tools-switch.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Utility functions for switching tools (= contexts) - * - * Authors: - * bulia byak - * - * Copyright (C) 2003 authors - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#ifndef SEEN_TOOLS_SWITCH_H -#define SEEN_TOOLS_SWITCH_H - -class SPDesktop; -class SPItem; -namespace Geom { -class Point; -} - - -enum { - TOOLS_INVALID, - TOOLS_SELECT, - TOOLS_NODES, - TOOLS_TWEAK, - TOOLS_SPRAY, - TOOLS_SHAPES_RECT, - TOOLS_SHAPES_3DBOX, - TOOLS_SHAPES_ARC, - TOOLS_SHAPES_STAR, - TOOLS_SHAPES_SPIRAL, - TOOLS_FREEHAND_PENCIL, - TOOLS_FREEHAND_PEN, - TOOLS_CALLIGRAPHIC, - TOOLS_TEXT, - TOOLS_GRADIENT, - TOOLS_MESH, - TOOLS_ZOOM, - TOOLS_MEASURE, - TOOLS_DROPPER, - TOOLS_CONNECTOR, - TOOLS_PAINTBUCKET, - TOOLS_ERASER, - TOOLS_LPETOOL -}; - -int tools_isactive(SPDesktop *dt, unsigned num); -int tools_active(SPDesktop *dt); -void tools_switch(SPDesktop *dt, int num); -void tools_switch_by_item (SPDesktop *dt, SPItem *item, Geom::Point const p); - -#endif // !SEEN_TOOLS_SWITCH_H - -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt index 0f6e560d2..8bae15fa5 100644 --- a/src/ui/CMakeLists.txt +++ b/src/ui/CMakeLists.txt @@ -3,8 +3,12 @@ set(ui_SRC clipboard.cpp control-manager.cpp dialog-events.cpp + draw-anchor.cpp interface.cpp + object-edit.cpp previewholder.cpp + shape-editor.cpp + tools-switch.cpp uxmanager.cpp cache/svg_preview_cache.cpp @@ -159,11 +163,15 @@ set(ui_SRC control-manager.h control-types.h dialog-events.h + draw-anchor.h icon-names.h interface.h + object-edit.h previewable.h previewfillable.h previewholder.h + shape-editor.h + tools-switch.h uxmanager.h cache/svg_preview_cache.h diff --git a/src/ui/Makefile_insert b/src/ui/Makefile_insert index 4c6b49ed6..7aeb4a83d 100644 --- a/src/ui/Makefile_insert +++ b/src/ui/Makefile_insert @@ -8,12 +8,21 @@ ink_common_sources += \ ui/control-types.h \ ui/dialog-events.cpp \ ui/dialog-events.h \ + ui/draw-anchor.cpp \ + ui/draw-anchor.h \ ui/icon-names.h \ ui/interface.cpp \ ui/interface.h \ + ui/object-edit.cpp \ + ui/object-edit.h \ ui/previewable.h \ ui/previewfillable.h \ ui/previewholder.cpp \ ui/previewholder.h \ + ui/shape-editor.cpp \ + ui/shape-editor.h \ + ui/tool-factory.h \ + ui/tools-switch.cpp \ + ui/tools-switch.h \ ui/uxmanager.cpp \ ui/uxmanager.h diff --git a/src/ui/clipboard.cpp b/src/ui/clipboard.cpp index 1209b19cd..40500cf15 100644 --- a/src/ui/clipboard.cpp +++ b/src/ui/clipboard.cpp @@ -76,7 +76,7 @@ #include "svg/css-ostringstream.h" // used in copy #include "ui/tools/text-tool.h" #include "text-editing.h" -#include "tools-switch.h" +#include "ui/tools-switch.h" #include "path-chemistry.h" #include "util/units.h" #include "helper/png-write.h" diff --git a/src/ui/dialog/align-and-distribute.cpp b/src/ui/dialog/align-and-distribute.cpp index 8352de1e3..431da7ad1 100644 --- a/src/ui/dialog/align-and-distribute.cpp +++ b/src/ui/dialog/align-and-distribute.cpp @@ -38,7 +38,7 @@ #include "sp-item-transform.h" #include "sp-text.h" #include "text-editing.h" -#include "tools-switch.h" +#include "ui/tools-switch.h" #include "ui/icon-names.h" #include "ui/tools/node-tool.h" #include "ui/tool/multi-path-manipulator.h" diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index 2a3a1dd86..071ac037f 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -31,13 +31,13 @@ #include "inkscape.h" #include "io/sys.h" #include "preferences.h" -#include "shape-editor.h" +#include "ui/shape-editor.h" #include "sp-namedview.h" #include "sp-root.h" #include "sp-script.h" #include "style.h" #include "svg/stringstream.h" -#include "tools-switch.h" +#include "ui/tools-switch.h" #include "ui/widget/color-picker.h" #include "ui/widget/scalar-unit.h" #include "ui/dialog/filedialog.h" diff --git a/src/ui/dialog/objects.cpp b/src/ui/dialog/objects.cpp index 07a27c96e..93d5dfbd5 100644 --- a/src/ui/dialog/objects.cpp +++ b/src/ui/dialog/objects.cpp @@ -43,7 +43,7 @@ #include "sp-root.h" #include "sp-shape.h" #include "style.h" -#include "tools-switch.h" +#include "ui/tools-switch.h" #include "ui/icon-names.h" #include "ui/widget/imagetoggler.h" #include "ui/widget/layertypeicon.h" diff --git a/src/ui/dialog/spellcheck.cpp b/src/ui/dialog/spellcheck.cpp index b8436ebf1..9faa8a2cb 100644 --- a/src/ui/dialog/spellcheck.cpp +++ b/src/ui/dialog/spellcheck.cpp @@ -23,7 +23,7 @@ #include "selection.h" #include "desktop.h" #include "desktop-handles.h" -#include "tools-switch.h" +#include "ui/tools-switch.h" #include "ui/tools/text-tool.h" #include "ui/interface.h" #include "preferences.h" diff --git a/src/ui/draw-anchor.cpp b/src/ui/draw-anchor.cpp new file mode 100644 index 000000000..84c919018 --- /dev/null +++ b/src/ui/draw-anchor.cpp @@ -0,0 +1,105 @@ +/** \file + * Anchors implementation. + */ + +/* + * Authors: + * Copyright (C) 2000 Lauris Kaplinski + * Copyright (C) 2000-2001 Ximian, Inc. + * Copyright (C) 2002 Lauris Kaplinski + * Copyright (C) 2004 Monash University + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + +#include "ui/draw-anchor.h" +#include "desktop.h" +#include "desktop-handles.h" +#include "ui/tools/tool-base.h" +#include "ui/tools/lpe-tool.h" +#include "display/sodipodi-ctrl.h" +#include "display/curve.h" +#include "ui/control-manager.h" + +using Inkscape::ControlManager; + +#define FILL_COLOR_NORMAL 0xffffff7f +#define FILL_COLOR_MOUSEOVER 0xff0000ff + +/** + * Creates an anchor object and initializes it. + */ +SPDrawAnchor *sp_draw_anchor_new(Inkscape::UI::Tools::FreehandBase *dc, SPCurve *curve, bool start, Geom::Point delta) +{ + if (SP_IS_LPETOOL_CONTEXT(dc)) { + // suppress all kinds of anchors in LPEToolContext + return NULL; + } + + SPDrawAnchor *a = g_new(SPDrawAnchor, 1); + + a->dc = dc; + a->curve = curve; + curve->ref(); + a->start = start; + a->active = FALSE; + a->dp = delta; + a->ctrl = ControlManager::getManager().createControl(sp_desktop_controls(&dc->getDesktop()), Inkscape::CTRL_TYPE_ANCHOR); + + SP_CTRL(a->ctrl)->moveto(delta); + + ControlManager::getManager().track(a->ctrl); + + return a; +} + +/** + * Destroys the anchor's canvas item and frees the anchor object. + */ +SPDrawAnchor *sp_draw_anchor_destroy(SPDrawAnchor *anchor) +{ + if (anchor->curve) { + anchor->curve->unref(); + } + if (anchor->ctrl) { + sp_canvas_item_destroy(anchor->ctrl); + } + g_free(anchor); + return NULL; +} + +/** + * Test if point is near anchor, if so fill anchor on canvas and return + * pointer to it or NULL. + */ +SPDrawAnchor *sp_draw_anchor_test(SPDrawAnchor *anchor, Geom::Point w, bool activate) +{ + SPCtrl *ctrl = SP_CTRL(anchor->ctrl); + + if ( activate && ( Geom::LInfty( w - anchor->dc->getDesktop().d2w(anchor->dp) ) <= (ctrl->box.width() / 2.0) ) ) { + if (!anchor->active) { + g_object_set(anchor->ctrl, "fill_color", FILL_COLOR_MOUSEOVER, NULL); + anchor->active = TRUE; + } + return anchor; + } + + if (anchor->active) { + g_object_set(anchor->ctrl, "fill_color", FILL_COLOR_NORMAL, NULL); + anchor->active = FALSE; + } + return NULL; +} + + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/draw-anchor.h b/src/ui/draw-anchor.h new file mode 100644 index 000000000..1f7b55920 --- /dev/null +++ b/src/ui/draw-anchor.h @@ -0,0 +1,52 @@ +#ifndef SEEN_DRAW_ANCHOR_H +#define SEEN_DRAW_ANCHOR_H + +/** \file + * Drawing anchors. + */ + +#include <2geom/point.h> + +namespace Inkscape { +namespace UI { +namespace Tools { + +class FreehandBase; + +} +} +} + +class SPCurve; +struct SPCanvasItem; + +/// The drawing anchor. +/// \todo Make this a regular knot, this will allow to set statusbar tips. +struct SPDrawAnchor { + Inkscape::UI::Tools::FreehandBase *dc; + SPCurve *curve; + unsigned int start : 1; + unsigned int active : 1; + Geom::Point dp; + SPCanvasItem *ctrl; +}; + + +SPDrawAnchor *sp_draw_anchor_new(Inkscape::UI::Tools::FreehandBase *dc, SPCurve *curve, bool start, + Geom::Point delta); +SPDrawAnchor *sp_draw_anchor_destroy(SPDrawAnchor *anchor); +SPDrawAnchor *sp_draw_anchor_test(SPDrawAnchor *anchor, Geom::Point w, bool activate); + + +#endif /* !SEEN_DRAW_ANCHOR_H */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/object-edit.cpp b/src/ui/object-edit.cpp new file mode 100644 index 000000000..cc96727f8 --- /dev/null +++ b/src/ui/object-edit.cpp @@ -0,0 +1,1399 @@ +/* + * Node editing extension to objects + * + * Authors: + * Lauris Kaplinski + * Mitsuru Oka + * Maximilian Albert + * Abhishek Sharma + * + * Licensed under GNU GPL + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + + + +#include "sp-item.h" +#include "sp-rect.h" +#include "box3d.h" +#include "sp-ellipse.h" +#include "sp-star.h" +#include "sp-spiral.h" +#include "sp-offset.h" +#include "sp-flowtext.h" +#include "preferences.h" +#include "style.h" +#include "desktop.h" +#include "desktop-handles.h" +#include "sp-namedview.h" +#include "live_effects/effect.h" +#include "sp-pattern.h" +#include "sp-path.h" +#include +#include "ui/object-edit.h" +#include "xml/repr.h" +#include <2geom/math-utils.h> +#include "knot-holder-entity.h" + +#define sp_round(v,m) (((v) < 0.0) ? ((ceil((v) / (m) - 0.5)) * (m)) : ((floor((v) / (m) + 0.5)) * (m))) + +namespace { + +static KnotHolder *sp_lpe_knot_holder(SPItem *item, SPDesktop *desktop) +{ + KnotHolder *knot_holder = new KnotHolder(desktop, item, NULL); + + Inkscape::LivePathEffect::Effect *effect = SP_LPE_ITEM(item)->getCurrentLPE(); + effect->addHandles(knot_holder, desktop, item); + + return knot_holder; +} + +} // namespace + +namespace Inkscape { +namespace UI { + +KnotHolder *createKnotHolder(SPItem *item, SPDesktop *desktop) +{ + KnotHolder *knotholder = NULL; + + if (SP_IS_LPE_ITEM(item) && + SP_LPE_ITEM(item)->getCurrentLPE() && + SP_LPE_ITEM(item)->getCurrentLPE()->isVisible() && + SP_LPE_ITEM(item)->getCurrentLPE()->providesKnotholder()) { + knotholder = sp_lpe_knot_holder(item, desktop); + } else if (SP_IS_RECT(item)) { + knotholder = new RectKnotHolder(desktop, item, NULL); + } else if (SP_IS_BOX3D(item)) { + knotholder = new Box3DKnotHolder(desktop, item, NULL); + } else if (SP_IS_GENERICELLIPSE(item)) { + knotholder = new ArcKnotHolder(desktop, item, NULL); + } else if (SP_IS_STAR(item)) { + knotholder = new StarKnotHolder(desktop, item, NULL); + } else if (SP_IS_SPIRAL(item)) { + knotholder = new SpiralKnotHolder(desktop, item, NULL); + } else if (SP_IS_OFFSET(item)) { + knotholder = new OffsetKnotHolder(desktop, item, NULL); + } else if (SP_IS_FLOWTEXT(item) && SP_FLOWTEXT(item)->has_internal_frame()) { + knotholder = new FlowtextKnotHolder(desktop, SP_FLOWTEXT(item)->get_frame(NULL), NULL); + } else if ((item->style->fill.isPaintserver() && SP_IS_PATTERN(item->style->getFillPaintServer())) || + (item->style->stroke.isPaintserver() && SP_IS_PATTERN(item->style->getStrokePaintServer()))) { + knotholder = new KnotHolder(desktop, item, NULL); + knotholder->add_pattern_knotholder(); + } + + return knotholder; +} + +} +} // namespace Inkscape + +/* SPRect */ + +/* handle for horizontal rounding radius */ +class RectKnotHolderEntityRX : public KnotHolderEntity { +public: + virtual Geom::Point knot_get() const; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); + virtual void knot_click(unsigned int state); +}; + +/* handle for vertical rounding radius */ +class RectKnotHolderEntityRY : public KnotHolderEntity { +public: + virtual Geom::Point knot_get() const; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); + virtual void knot_click(unsigned int state); +}; + +/* handle for width/height adjustment */ +class RectKnotHolderEntityWH : public KnotHolderEntity { +public: + virtual Geom::Point knot_get() const; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); + +protected: + void set_internal(Geom::Point const &p, Geom::Point const &origin, unsigned int state); +}; + +/* handle for x/y adjustment */ +class RectKnotHolderEntityXY : public KnotHolderEntity { +public: + virtual Geom::Point knot_get() const; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); +}; + +Geom::Point +RectKnotHolderEntityRX::knot_get() const +{ + SPRect *rect = SP_RECT(item); + + return Geom::Point(rect->x.computed + rect->width.computed - rect->rx.computed, rect->y.computed); +} + +void +RectKnotHolderEntityRX::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, unsigned int state) +{ + SPRect *rect = SP_RECT(item); + + //In general we cannot just snap this radius to an arbitrary point, as we have only a single + //degree of freedom. For snapping to an arbitrary point we need two DOF. If we're going to snap + //the radius then we should have a constrained snap. snap_knot_position() is unconstrained + Geom::Point const s = snap_knot_position_constrained(p, Inkscape::Snapper::SnapConstraint(Geom::Point(rect->x.computed + rect->width.computed, rect->y.computed), Geom::Point(-1, 0)), state); + + if (state & GDK_CONTROL_MASK) { + gdouble temp = MIN(rect->height.computed, rect->width.computed) / 2.0; + rect->rx.computed = rect->ry.computed = CLAMP(rect->x.computed + rect->width.computed - s[Geom::X], 0.0, temp); + rect->rx._set = rect->ry._set = true; + + } else { + rect->rx.computed = CLAMP(rect->x.computed + rect->width.computed - s[Geom::X], 0.0, rect->width.computed / 2.0); + rect->rx._set = true; + } + + update_knot(); + + (static_cast(rect))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + +void +RectKnotHolderEntityRX::knot_click(unsigned int state) +{ + SPRect *rect = SP_RECT(item); + + if (state & GDK_SHIFT_MASK) { + /* remove rounding from rectangle */ + rect->getRepr()->setAttribute("rx", NULL); + rect->getRepr()->setAttribute("ry", NULL); + } else if (state & GDK_CONTROL_MASK) { + /* Ctrl-click sets the vertical rounding to be the same as the horizontal */ + rect->getRepr()->setAttribute("ry", rect->getRepr()->attribute("rx")); + } + +} + +Geom::Point +RectKnotHolderEntityRY::knot_get() const +{ + SPRect *rect = SP_RECT(item); + + return Geom::Point(rect->x.computed + rect->width.computed, rect->y.computed + rect->ry.computed); +} + +void +RectKnotHolderEntityRY::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, unsigned int state) +{ + SPRect *rect = SP_RECT(item); + + //In general we cannot just snap this radius to an arbitrary point, as we have only a single + //degree of freedom. For snapping to an arbitrary point we need two DOF. If we're going to snap + //the radius then we should have a constrained snap. snap_knot_position() is unconstrained + Geom::Point const s = snap_knot_position_constrained(p, Inkscape::Snapper::SnapConstraint(Geom::Point(rect->x.computed + rect->width.computed, rect->y.computed), Geom::Point(0, 1)), state); + + if (state & GDK_CONTROL_MASK) { // When holding control then rx will be kept equal to ry, + // resulting in a perfect circle (and not an ellipse) + gdouble temp = MIN(rect->height.computed, rect->width.computed) / 2.0; + rect->rx.computed = rect->ry.computed = CLAMP(s[Geom::Y] - rect->y.computed, 0.0, temp); + rect->ry._set = rect->rx._set = true; + } else { + if (!rect->rx._set || rect->rx.computed == 0) { + rect->ry.computed = CLAMP(s[Geom::Y] - rect->y.computed, + 0.0, + MIN(rect->height.computed / 2.0, rect->width.computed / 2.0)); + } else { + rect->ry.computed = CLAMP(s[Geom::Y] - rect->y.computed, + 0.0, + rect->height.computed / 2.0); + } + + rect->ry._set = true; + } + + update_knot(); + + (static_cast(rect))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + +void +RectKnotHolderEntityRY::knot_click(unsigned int state) +{ + SPRect *rect = SP_RECT(item); + + if (state & GDK_SHIFT_MASK) { + /* remove rounding */ + rect->getRepr()->setAttribute("rx", NULL); + rect->getRepr()->setAttribute("ry", NULL); + } else if (state & GDK_CONTROL_MASK) { + /* Ctrl-click sets the vertical rounding to be the same as the horizontal */ + rect->getRepr()->setAttribute("rx", rect->getRepr()->attribute("ry")); + } +} + +#define SGN(x) ((x)>0?1:((x)<0?-1:0)) + +static void sp_rect_clamp_radii(SPRect *rect) +{ + // clamp rounding radii so that they do not exceed width/height + if (2 * rect->rx.computed > rect->width.computed) { + rect->rx.computed = 0.5 * rect->width.computed; + rect->rx._set = true; + } + if (2 * rect->ry.computed > rect->height.computed) { + rect->ry.computed = 0.5 * rect->height.computed; + rect->ry._set = true; + } +} + +Geom::Point +RectKnotHolderEntityWH::knot_get() const +{ + SPRect *rect = SP_RECT(item); + + return Geom::Point(rect->x.computed + rect->width.computed, rect->y.computed + rect->height.computed); +} + +void +RectKnotHolderEntityWH::set_internal(Geom::Point const &p, Geom::Point const &origin, unsigned int state) +{ + SPRect *rect = SP_RECT(item); + + Geom::Point s = p; + + if (state & GDK_CONTROL_MASK) { + // original width/height when drag started + gdouble const w_orig = (origin[Geom::X] - rect->x.computed); + gdouble const h_orig = (origin[Geom::Y] - rect->y.computed); + + //original ratio + gdouble ratio = (w_orig / h_orig); + + // mouse displacement since drag started + gdouble minx = p[Geom::X] - origin[Geom::X]; + gdouble miny = p[Geom::Y] - origin[Geom::Y]; + + Geom::Point p_handle(rect->x.computed + rect->width.computed, rect->y.computed + rect->height.computed); + + if (fabs(minx) > fabs(miny)) { + // snap to horizontal or diagonal + if (minx != 0 && fabs(miny/minx) > 0.5 * 1/ratio && (SGN(minx) == SGN(miny))) { + // closer to the diagonal and in same-sign quarters, change both using ratio + s = snap_knot_position_constrained(p, Inkscape::Snapper::SnapConstraint(p_handle, Geom::Point(-ratio, -1)), state); + minx = s[Geom::X] - origin[Geom::X]; + miny = s[Geom::Y] - origin[Geom::Y]; + rect->height.computed = MAX(h_orig + minx / ratio, 0); + } else { + // closer to the horizontal, change only width, height is h_orig + s = snap_knot_position_constrained(p, Inkscape::Snapper::SnapConstraint(p_handle, Geom::Point(-1, 0)), state); + minx = s[Geom::X] - origin[Geom::X]; + miny = s[Geom::Y] - origin[Geom::Y]; + rect->height.computed = MAX(h_orig, 0); + } + rect->width.computed = MAX(w_orig + minx, 0); + + } else { + // snap to vertical or diagonal + if (miny != 0 && fabs(minx/miny) > 0.5 * ratio && (SGN(minx) == SGN(miny))) { + // closer to the diagonal and in same-sign quarters, change both using ratio + s = snap_knot_position_constrained(p, Inkscape::Snapper::SnapConstraint(p_handle, Geom::Point(-ratio, -1)), state); + minx = s[Geom::X] - origin[Geom::X]; + miny = s[Geom::Y] - origin[Geom::Y]; + rect->width.computed = MAX(w_orig + miny * ratio, 0); + } else { + // closer to the vertical, change only height, width is w_orig + s = snap_knot_position_constrained(p, Inkscape::Snapper::SnapConstraint(p_handle, Geom::Point(0, -1)), state); + minx = s[Geom::X] - origin[Geom::X]; + miny = s[Geom::Y] - origin[Geom::Y]; + rect->width.computed = MAX(w_orig, 0); + } + rect->height.computed = MAX(h_orig + miny, 0); + + } + + rect->width._set = rect->height._set = true; + + } else { + // move freely + s = snap_knot_position(p, state); + rect->width.computed = MAX(s[Geom::X] - rect->x.computed, 0); + rect->height.computed = MAX(s[Geom::Y] - rect->y.computed, 0); + rect->width._set = rect->height._set = true; + } + + sp_rect_clamp_radii(rect); + + (static_cast(rect))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + +void +RectKnotHolderEntityWH::knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state) +{ + set_internal(p, origin, state); + update_knot(); +} + +Geom::Point +RectKnotHolderEntityXY::knot_get() const +{ + SPRect *rect = SP_RECT(item); + + return Geom::Point(rect->x.computed, rect->y.computed); +} + +void +RectKnotHolderEntityXY::knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state) +{ + SPRect *rect = SP_RECT(item); + + // opposite corner (unmoved) + gdouble opposite_x = (rect->x.computed + rect->width.computed); + gdouble opposite_y = (rect->y.computed + rect->height.computed); + + // original width/height when drag started + gdouble w_orig = opposite_x - origin[Geom::X]; + gdouble h_orig = opposite_y - origin[Geom::Y]; + + Geom::Point s = p; + Geom::Point p_handle(rect->x.computed, rect->y.computed); + + // mouse displacement since drag started + gdouble minx = p[Geom::X] - origin[Geom::X]; + gdouble miny = p[Geom::Y] - origin[Geom::Y]; + + if (state & GDK_CONTROL_MASK) { + //original ratio + gdouble ratio = (w_orig / h_orig); + + if (fabs(minx) > fabs(miny)) { + // snap to horizontal or diagonal + if (minx != 0 && fabs(miny/minx) > 0.5 * 1/ratio && (SGN(minx) == SGN(miny))) { + // closer to the diagonal and in same-sign quarters, change both using ratio + s = snap_knot_position_constrained(p, Inkscape::Snapper::SnapConstraint(p_handle, Geom::Point(-ratio, -1)), state); + minx = s[Geom::X] - origin[Geom::X]; + miny = s[Geom::Y] - origin[Geom::Y]; + rect->y.computed = MIN(origin[Geom::Y] + minx / ratio, opposite_y); + rect->height.computed = MAX(h_orig - minx / ratio, 0); + } else { + // closer to the horizontal, change only width, height is h_orig + s = snap_knot_position_constrained(p, Inkscape::Snapper::SnapConstraint(p_handle, Geom::Point(-1, 0)), state); + minx = s[Geom::X] - origin[Geom::X]; + miny = s[Geom::Y] - origin[Geom::Y]; + rect->y.computed = MIN(origin[Geom::Y], opposite_y); + rect->height.computed = MAX(h_orig, 0); + } + rect->x.computed = MIN(s[Geom::X], opposite_x); + rect->width.computed = MAX(w_orig - minx, 0); + } else { + // snap to vertical or diagonal + if (miny != 0 && fabs(minx/miny) > 0.5 *ratio && (SGN(minx) == SGN(miny))) { + // closer to the diagonal and in same-sign quarters, change both using ratio + s = snap_knot_position_constrained(p, Inkscape::Snapper::SnapConstraint(p_handle, Geom::Point(-ratio, -1)), state); + minx = s[Geom::X] - origin[Geom::X]; + miny = s[Geom::Y] - origin[Geom::Y]; + rect->x.computed = MIN(origin[Geom::X] + miny * ratio, opposite_x); + rect->width.computed = MAX(w_orig - miny * ratio, 0); + } else { + // closer to the vertical, change only height, width is w_orig + s = snap_knot_position_constrained(p, Inkscape::Snapper::SnapConstraint(p_handle, Geom::Point(0, -1)), state); + minx = s[Geom::X] - origin[Geom::X]; + miny = s[Geom::Y] - origin[Geom::Y]; + rect->x.computed = MIN(origin[Geom::X], opposite_x); + rect->width.computed = MAX(w_orig, 0); + } + rect->y.computed = MIN(s[Geom::Y], opposite_y); + rect->height.computed = MAX(h_orig - miny, 0); + } + + rect->width._set = rect->height._set = rect->x._set = rect->y._set = true; + + } else { + // move freely + s = snap_knot_position(p, state); + minx = s[Geom::X] - origin[Geom::X]; + miny = s[Geom::Y] - origin[Geom::Y]; + + rect->x.computed = MIN(s[Geom::X], opposite_x); + rect->width.computed = MAX(w_orig - minx, 0); + rect->y.computed = MIN(s[Geom::Y], opposite_y); + rect->height.computed = MAX(h_orig - miny, 0); + rect->width._set = rect->height._set = rect->x._set = rect->y._set = true; + } + + sp_rect_clamp_radii(rect); + + update_knot(); + + (static_cast(rect))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + +RectKnotHolder::RectKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler) : + KnotHolder(desktop, item, relhandler) +{ + RectKnotHolderEntityRX *entity_rx = new RectKnotHolderEntityRX(); + RectKnotHolderEntityRY *entity_ry = new RectKnotHolderEntityRY(); + RectKnotHolderEntityWH *entity_wh = new RectKnotHolderEntityWH(); + RectKnotHolderEntityXY *entity_xy = new RectKnotHolderEntityXY(); + + entity_rx->create(desktop, item, this, Inkscape::CTRL_TYPE_ROTATE, + _("Adjust the horizontal rounding radius; with Ctrl " + "to make the vertical radius the same"), + SP_KNOT_SHAPE_CIRCLE, SP_KNOT_MODE_XOR); + + entity_ry->create(desktop, item, this, Inkscape::CTRL_TYPE_ROTATE, + _("Adjust the vertical rounding radius; with Ctrl " + "to make the horizontal radius the same"), + SP_KNOT_SHAPE_CIRCLE, SP_KNOT_MODE_XOR); + + entity_wh->create(desktop, item, this, Inkscape::CTRL_TYPE_SIZER, + _("Adjust the width and height of the rectangle; with Ctrl " + "to lock ratio or stretch in one dimension only"), + SP_KNOT_SHAPE_SQUARE, SP_KNOT_MODE_XOR); + + entity_xy->create(desktop, item, this, Inkscape::CTRL_TYPE_SIZER, + _("Adjust the width and height of the rectangle; with Ctrl " + "to lock ratio or stretch in one dimension only"), + SP_KNOT_SHAPE_SQUARE, SP_KNOT_MODE_XOR); + + entity.push_back(entity_rx); + entity.push_back(entity_ry); + entity.push_back(entity_wh); + entity.push_back(entity_xy); + + add_pattern_knotholder(); +} + +/* Box3D (= the new 3D box structure) */ + +class Box3DKnotHolderEntity : public KnotHolderEntity { +public: + virtual Geom::Point knot_get() const = 0; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state) = 0; + + Geom::Point knot_get_generic(SPItem *item, unsigned int knot_id) const; + void knot_set_generic(SPItem *item, unsigned int knot_id, Geom::Point const &p, unsigned int state); +}; + +Geom::Point +Box3DKnotHolderEntity::knot_get_generic(SPItem *item, unsigned int knot_id) const +{ + return box3d_get_corner_screen(SP_BOX3D(item), knot_id); +} + +void +Box3DKnotHolderEntity::knot_set_generic(SPItem *item, unsigned int knot_id, Geom::Point const &new_pos, unsigned int state) +{ + Geom::Point const s = snap_knot_position(new_pos, state); + + g_assert(item != NULL); + SPBox3D *box = SP_BOX3D(item); + Geom::Affine const i2dt (item->i2dt_affine ()); + + Box3D::Axis movement; + if ((knot_id < 4) != (state & GDK_SHIFT_MASK)) { + movement = Box3D::XY; + } else { + movement = Box3D::Z; + } + + box3d_set_corner (box, knot_id, s * i2dt, movement, (state & GDK_CONTROL_MASK)); + box3d_set_z_orders(box); + box3d_position_set(box); +} + +class Box3DKnotHolderEntity0 : public Box3DKnotHolderEntity { +public: + virtual Geom::Point knot_get() const; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); +}; + +class Box3DKnotHolderEntity1 : public Box3DKnotHolderEntity { +public: + virtual Geom::Point knot_get() const; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); +}; + +class Box3DKnotHolderEntity2 : public Box3DKnotHolderEntity { +public: + virtual Geom::Point knot_get() const; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); +}; + +class Box3DKnotHolderEntity3 : public Box3DKnotHolderEntity { +public: + virtual Geom::Point knot_get() const; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); +}; + +class Box3DKnotHolderEntity4 : public Box3DKnotHolderEntity { +public: + virtual Geom::Point knot_get() const; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); +}; + +class Box3DKnotHolderEntity5 : public Box3DKnotHolderEntity { +public: + virtual Geom::Point knot_get() const; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); +}; + +class Box3DKnotHolderEntity6 : public Box3DKnotHolderEntity { +public: + virtual Geom::Point knot_get() const; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); +}; + +class Box3DKnotHolderEntity7 : public Box3DKnotHolderEntity { +public: + virtual Geom::Point knot_get() const; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); +}; + +class Box3DKnotHolderEntityCenter : public KnotHolderEntity { +public: + virtual Geom::Point knot_get() const; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); +}; + +Geom::Point +Box3DKnotHolderEntity0::knot_get() const +{ + return knot_get_generic(item, 0); +} + +Geom::Point +Box3DKnotHolderEntity1::knot_get() const +{ + return knot_get_generic(item, 1); +} + +Geom::Point +Box3DKnotHolderEntity2::knot_get() const +{ + return knot_get_generic(item, 2); +} + +Geom::Point +Box3DKnotHolderEntity3::knot_get() const +{ + return knot_get_generic(item, 3); +} + +Geom::Point +Box3DKnotHolderEntity4::knot_get() const +{ + return knot_get_generic(item, 4); +} + +Geom::Point +Box3DKnotHolderEntity5::knot_get() const +{ + return knot_get_generic(item, 5); +} + +Geom::Point +Box3DKnotHolderEntity6::knot_get() const +{ + return knot_get_generic(item, 6); +} + +Geom::Point +Box3DKnotHolderEntity7::knot_get() const +{ + return knot_get_generic(item, 7); +} + +Geom::Point +Box3DKnotHolderEntityCenter::knot_get() const +{ + return box3d_get_center_screen(SP_BOX3D(item)); +} + +void +Box3DKnotHolderEntity0::knot_set(Geom::Point const &new_pos, Geom::Point const &/*origin*/, unsigned int state) +{ + knot_set_generic(item, 0, new_pos, state); +} + +void +Box3DKnotHolderEntity1::knot_set(Geom::Point const &new_pos, Geom::Point const &/*origin*/, unsigned int state) +{ + knot_set_generic(item, 1, new_pos, state); +} + +void +Box3DKnotHolderEntity2::knot_set(Geom::Point const &new_pos, Geom::Point const &/*origin*/, unsigned int state) +{ + knot_set_generic(item, 2, new_pos, state); +} + +void +Box3DKnotHolderEntity3::knot_set(Geom::Point const &new_pos, Geom::Point const &/*origin*/, unsigned int state) +{ + knot_set_generic(item, 3, new_pos, state); +} + +void +Box3DKnotHolderEntity4::knot_set(Geom::Point const &new_pos, Geom::Point const &/*origin*/, unsigned int state) +{ + knot_set_generic(item, 4, new_pos, state); +} + +void +Box3DKnotHolderEntity5::knot_set(Geom::Point const &new_pos, Geom::Point const &/*origin*/, unsigned int state) +{ + knot_set_generic(item, 5, new_pos, state); +} + +void +Box3DKnotHolderEntity6::knot_set(Geom::Point const &new_pos, Geom::Point const &/*origin*/, unsigned int state) +{ + knot_set_generic(item, 6, new_pos, state); +} + +void +Box3DKnotHolderEntity7::knot_set(Geom::Point const &new_pos, Geom::Point const &/*origin*/, unsigned int state) +{ + knot_set_generic(item, 7, new_pos, state); +} + +void +Box3DKnotHolderEntityCenter::knot_set(Geom::Point const &new_pos, Geom::Point const &origin, unsigned int state) +{ + Geom::Point const s = snap_knot_position(new_pos, state); + + SPBox3D *box = SP_BOX3D(item); + Geom::Affine const i2dt (item->i2dt_affine ()); + + box3d_set_center (SP_BOX3D(item), s * i2dt, origin * i2dt, !(state & GDK_SHIFT_MASK) ? Box3D::XY : Box3D::Z, + state & GDK_CONTROL_MASK); + + box3d_set_z_orders(box); + box3d_position_set(box); +} + +Box3DKnotHolder::Box3DKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler) : + KnotHolder(desktop, item, relhandler) +{ + Box3DKnotHolderEntity0 *entity_corner0 = new Box3DKnotHolderEntity0(); + Box3DKnotHolderEntity1 *entity_corner1 = new Box3DKnotHolderEntity1(); + Box3DKnotHolderEntity2 *entity_corner2 = new Box3DKnotHolderEntity2(); + Box3DKnotHolderEntity3 *entity_corner3 = new Box3DKnotHolderEntity3(); + Box3DKnotHolderEntity4 *entity_corner4 = new Box3DKnotHolderEntity4(); + Box3DKnotHolderEntity5 *entity_corner5 = new Box3DKnotHolderEntity5(); + Box3DKnotHolderEntity6 *entity_corner6 = new Box3DKnotHolderEntity6(); + Box3DKnotHolderEntity7 *entity_corner7 = new Box3DKnotHolderEntity7(); + Box3DKnotHolderEntityCenter *entity_center = new Box3DKnotHolderEntityCenter(); + + entity_corner0->create(desktop, item, this, Inkscape::CTRL_TYPE_SHAPER, + _("Resize box in X/Y direction; with Shift along the Z axis; " + "with Ctrl to constrain to the directions of edges or diagonals")); + + entity_corner1->create(desktop, item, this, Inkscape::CTRL_TYPE_SHAPER, + _("Resize box in X/Y direction; with Shift along the Z axis; " + "with Ctrl to constrain to the directions of edges or diagonals")); + + entity_corner2->create(desktop, item, this, Inkscape::CTRL_TYPE_SHAPER, + _("Resize box in X/Y direction; with Shift along the Z axis; " + "with Ctrl to constrain to the directions of edges or diagonals")); + + entity_corner3->create(desktop, item, this, Inkscape::CTRL_TYPE_SHAPER, + _("Resize box in X/Y direction; with Shift along the Z axis; " + "with Ctrl to constrain to the directions of edges or diagonals")); + + entity_corner4->create(desktop, item, this, Inkscape::CTRL_TYPE_SHAPER, + _("Resize box along the Z axis; with Shift in X/Y direction; " + "with Ctrl to constrain to the directions of edges or diagonals")); + + entity_corner5->create(desktop, item, this, Inkscape::CTRL_TYPE_SHAPER, + _("Resize box along the Z axis; with Shift in X/Y direction; " + "with Ctrl to constrain to the directions of edges or diagonals")); + + entity_corner6->create(desktop, item, this, Inkscape::CTRL_TYPE_SHAPER, + _("Resize box along the Z axis; with Shift in X/Y direction; " + "with Ctrl to constrain to the directions of edges or diagonals")); + + entity_corner7->create(desktop, item, this, Inkscape::CTRL_TYPE_SHAPER, + _("Resize box along the Z axis; with Shift in X/Y direction; " + "with Ctrl to constrain to the directions of edges or diagonals")); + + entity_center->create(desktop, item, this, Inkscape::CTRL_TYPE_POINT, + _("Move the box in perspective"), + SP_KNOT_SHAPE_CROSS); + + entity.push_back(entity_corner0); + entity.push_back(entity_corner1); + entity.push_back(entity_corner2); + entity.push_back(entity_corner3); + entity.push_back(entity_corner4); + entity.push_back(entity_corner5); + entity.push_back(entity_corner6); + entity.push_back(entity_corner7); + entity.push_back(entity_center); + + add_pattern_knotholder(); +} + +/* SPArc */ + +class ArcKnotHolderEntityStart : public KnotHolderEntity { +public: + virtual Geom::Point knot_get() const; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); + virtual void knot_click(unsigned int state); +}; + +class ArcKnotHolderEntityEnd : public KnotHolderEntity { +public: + virtual Geom::Point knot_get() const; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); + virtual void knot_click(unsigned int state); +}; + +class ArcKnotHolderEntityRX : public KnotHolderEntity { +public: + virtual Geom::Point knot_get() const; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); + virtual void knot_click(unsigned int state); +}; + +class ArcKnotHolderEntityRY : public KnotHolderEntity { +public: + virtual Geom::Point knot_get() const; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); + virtual void knot_click(unsigned int state); +}; + +/* + * return values: + * 1 : inside + * 0 : on the curves + * -1 : outside + */ +static gint +sp_genericellipse_side(SPGenericEllipse *ellipse, Geom::Point const &p) +{ + gdouble dx = (p[Geom::X] - ellipse->cx.computed) / ellipse->rx.computed; + gdouble dy = (p[Geom::Y] - ellipse->cy.computed) / ellipse->ry.computed; + + gdouble s = dx * dx + dy * dy; + if (s < 1.0) return 1; + if (s > 1.0) return -1; + return 0; +} + +void +ArcKnotHolderEntityStart::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, unsigned int state) +{ + int snaps = Inkscape::Preferences::get()->getInt("/options/rotationsnapsperpi/value", 12); + + SPGenericEllipse *arc = SP_GENERICELLIPSE(item); + + arc->setClosed(sp_genericellipse_side(arc, p) == -1); + + Geom::Point delta = p - Geom::Point(arc->cx.computed, arc->cy.computed); + Geom::Scale sc(arc->rx.computed, arc->ry.computed); + + arc->start = atan2(delta * sc.inverse()); + + if ((state & GDK_CONTROL_MASK) && snaps) { + arc->start = sp_round(arc->start, M_PI / snaps); + } + + arc->normalize(); + arc->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + +Geom::Point +ArcKnotHolderEntityStart::knot_get() const +{ + SPGenericEllipse const *ge = SP_GENERICELLIPSE(item); + + return ge->getPointAtAngle(ge->start); +} + +void +ArcKnotHolderEntityStart::knot_click(unsigned int state) +{ + SPGenericEllipse *ge = SP_GENERICELLIPSE(item); + + if (state & GDK_SHIFT_MASK) { + ge->end = ge->start = 0; + (static_cast(ge))->updateRepr(); + } +} + +void +ArcKnotHolderEntityEnd::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, unsigned int state) +{ + int snaps = Inkscape::Preferences::get()->getInt("/options/rotationsnapsperpi/value", 12); + + SPGenericEllipse *arc = SP_GENERICELLIPSE(item); + + arc->setClosed(sp_genericellipse_side(arc, p) == -1); + + Geom::Point delta = p - Geom::Point(arc->cx.computed, arc->cy.computed); + Geom::Scale sc(arc->rx.computed, arc->ry.computed); + + arc->end = atan2(delta * sc.inverse()); + + if ((state & GDK_CONTROL_MASK) && snaps) { + arc->end = sp_round(arc->end, M_PI/snaps); + } + + arc->normalize(); + arc->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + +Geom::Point +ArcKnotHolderEntityEnd::knot_get() const +{ + SPGenericEllipse const *ge = SP_GENERICELLIPSE(item); + + return ge->getPointAtAngle(ge->end); +} + + +void +ArcKnotHolderEntityEnd::knot_click(unsigned int state) +{ + SPGenericEllipse *ge = SP_GENERICELLIPSE(item); + + if (state & GDK_SHIFT_MASK) { + ge->end = ge->start = 0; + (static_cast(ge))->updateRepr(); + } +} + + +void +ArcKnotHolderEntityRX::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, unsigned int state) +{ + SPGenericEllipse *ge = SP_GENERICELLIPSE(item); + + Geom::Point const s = snap_knot_position(p, state); + + ge->rx.computed = fabs( ge->cx.computed - s[Geom::X] ); + + if ( state & GDK_CONTROL_MASK ) { + ge->ry.computed = ge->rx.computed; + } + + (static_cast(item))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + +Geom::Point +ArcKnotHolderEntityRX::knot_get() const +{ + SPGenericEllipse const *ge = SP_GENERICELLIPSE(item); + + return (Geom::Point(ge->cx.computed, ge->cy.computed) - Geom::Point(ge->rx.computed, 0)); +} + +void +ArcKnotHolderEntityRX::knot_click(unsigned int state) +{ + SPGenericEllipse *ge = SP_GENERICELLIPSE(item); + + if (state & GDK_CONTROL_MASK) { + ge->ry.computed = ge->rx.computed; + (static_cast(ge))->updateRepr(); + } +} + +void +ArcKnotHolderEntityRY::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, unsigned int state) +{ + SPGenericEllipse *ge = SP_GENERICELLIPSE(item); + + Geom::Point const s = snap_knot_position(p, state); + + ge->ry.computed = fabs( ge->cy.computed - s[Geom::Y] ); + + if ( state & GDK_CONTROL_MASK ) { + ge->rx.computed = ge->ry.computed; + } + + (static_cast(item))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + +Geom::Point +ArcKnotHolderEntityRY::knot_get() const +{ + SPGenericEllipse const *ge = SP_GENERICELLIPSE(item); + + return (Geom::Point(ge->cx.computed, ge->cy.computed) - Geom::Point(0, ge->ry.computed)); +} + +void +ArcKnotHolderEntityRY::knot_click(unsigned int state) +{ + SPGenericEllipse *ge = SP_GENERICELLIPSE(item); + + if (state & GDK_CONTROL_MASK) { + ge->rx.computed = ge->ry.computed; + (static_cast(ge))->updateRepr(); + } +} + +ArcKnotHolder::ArcKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler) : + KnotHolder(desktop, item, relhandler) +{ + ArcKnotHolderEntityRX *entity_rx = new ArcKnotHolderEntityRX(); + ArcKnotHolderEntityRY *entity_ry = new ArcKnotHolderEntityRY(); + ArcKnotHolderEntityStart *entity_start = new ArcKnotHolderEntityStart(); + ArcKnotHolderEntityEnd *entity_end = new ArcKnotHolderEntityEnd(); + + entity_rx->create(desktop, item, this, Inkscape::CTRL_TYPE_SIZER, + _("Adjust ellipse width, with Ctrl to make circle"), + SP_KNOT_SHAPE_SQUARE, SP_KNOT_MODE_XOR); + + entity_ry->create(desktop, item, this, Inkscape::CTRL_TYPE_SIZER, + _("Adjust ellipse height, with Ctrl to make circle"), + SP_KNOT_SHAPE_SQUARE, SP_KNOT_MODE_XOR); + + entity_start->create(desktop, item, this, Inkscape::CTRL_TYPE_ROTATE, + _("Position the start point of the arc or segment; with Ctrl " + "to snap angle; drag inside the ellipse for arc, outside for segment"), + SP_KNOT_SHAPE_CIRCLE, SP_KNOT_MODE_XOR); + + entity_end->create(desktop, item, this, Inkscape::CTRL_TYPE_ROTATE, + _("Position the end point of the arc or segment; with Ctrl to snap angle; " + "drag inside the ellipse for arc, outside for segment"), + SP_KNOT_SHAPE_CIRCLE, SP_KNOT_MODE_XOR); + + entity.push_back(entity_rx); + entity.push_back(entity_ry); + entity.push_back(entity_start); + entity.push_back(entity_end); + + add_pattern_knotholder(); +} + +/* SPStar */ + +class StarKnotHolderEntity1 : public KnotHolderEntity { +public: + virtual Geom::Point knot_get() const; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); + virtual void knot_click(unsigned int state); +}; + +class StarKnotHolderEntity2 : public KnotHolderEntity { +public: + virtual Geom::Point knot_get() const; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); + virtual void knot_click(unsigned int state); +}; + +void +StarKnotHolderEntity1::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, unsigned int state) +{ + SPStar *star = SP_STAR(item); + + Geom::Point const s = snap_knot_position(p, state); + + Geom::Point d = s - star->center; + + double arg1 = atan2(d); + double darg1 = arg1 - star->arg[0]; + + if (state & GDK_MOD1_MASK) { + star->randomized = darg1/(star->arg[0] - star->arg[1]); + } else if (state & GDK_SHIFT_MASK) { + star->rounded = darg1/(star->arg[0] - star->arg[1]); + } else if (state & GDK_CONTROL_MASK) { + star->r[0] = L2(d); + } else { + star->r[0] = L2(d); + star->arg[0] = arg1; + star->arg[1] += darg1; + } + (static_cast(star))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + +void +StarKnotHolderEntity2::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, unsigned int state) +{ + SPStar *star = SP_STAR(item); + + Geom::Point const s = snap_knot_position(p, state); + + if (star->flatsided == false) { + Geom::Point d = s - star->center; + + double arg1 = atan2(d); + double darg1 = arg1 - star->arg[1]; + + if (state & GDK_MOD1_MASK) { + star->randomized = darg1/(star->arg[0] - star->arg[1]); + } else if (state & GDK_SHIFT_MASK) { + star->rounded = fabs(darg1/(star->arg[0] - star->arg[1])); + } else if (state & GDK_CONTROL_MASK) { + star->r[1] = L2(d); + star->arg[1] = star->arg[0] + M_PI / star->sides; + } + else { + star->r[1] = L2(d); + star->arg[1] = atan2(d); + } + (static_cast(star))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + } +} + +Geom::Point +StarKnotHolderEntity1::knot_get() const +{ + g_assert(item != NULL); + + SPStar const *star = SP_STAR(item); + + return sp_star_get_xy(star, SP_STAR_POINT_KNOT1, 0); + +} + +Geom::Point +StarKnotHolderEntity2::knot_get() const +{ + g_assert(item != NULL); + + SPStar const *star = SP_STAR(item); + + return sp_star_get_xy(star, SP_STAR_POINT_KNOT2, 0); +} + +static void +sp_star_knot_click(SPItem *item, unsigned int state) +{ + SPStar *star = SP_STAR(item); + + if (state & GDK_MOD1_MASK) { + star->randomized = 0; + (static_cast(star))->updateRepr(); + } else if (state & GDK_SHIFT_MASK) { + star->rounded = 0; + (static_cast(star))->updateRepr(); + } else if (state & GDK_CONTROL_MASK) { + star->arg[1] = star->arg[0] + M_PI / star->sides; + (static_cast(star))->updateRepr(); + } +} + +void +StarKnotHolderEntity1::knot_click(unsigned int state) +{ + sp_star_knot_click(item, state); +} + +void +StarKnotHolderEntity2::knot_click(unsigned int state) +{ + sp_star_knot_click(item, state); +} + +StarKnotHolder::StarKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler) : + KnotHolder(desktop, item, relhandler) +{ + SPStar *star = SP_STAR(item); + + StarKnotHolderEntity1 *entity1 = new StarKnotHolderEntity1(); + entity1->create(desktop, item, this, Inkscape::CTRL_TYPE_SHAPER, + _("Adjust the tip radius of the star or polygon; " + "with Shift to round; with Alt to randomize")); + + entity.push_back(entity1); + + if (star->flatsided == false) { + StarKnotHolderEntity2 *entity2 = new StarKnotHolderEntity2(); + entity2->create(desktop, item, this, Inkscape::CTRL_TYPE_SHAPER, + _("Adjust the base radius of the star; with Ctrl to keep star rays " + "radial (no skew); with Shift to round; with Alt to randomize")); + entity.push_back(entity2); + } + + add_pattern_knotholder(); +} + +/* SPSpiral */ + +class SpiralKnotHolderEntityInner : public KnotHolderEntity { +public: + virtual Geom::Point knot_get() const; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); + virtual void knot_click(unsigned int state); +}; + +class SpiralKnotHolderEntityOuter : public KnotHolderEntity { +public: + virtual Geom::Point knot_get() const; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); +}; + + +/* + * set attributes via inner (t=t0) knot point: + * [default] increase/decrease inner point + * [shift] increase/decrease inner and outer arg synchronizely + * [control] constrain inner arg to round per PI/4 + */ +void +SpiralKnotHolderEntityInner::knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + int snaps = prefs->getInt("/options/rotationsnapsperpi/value", 12); + + SPSpiral *spiral = SP_SPIRAL(item); + + gdouble dx = p[Geom::X] - spiral->cx; + gdouble dy = p[Geom::Y] - spiral->cy; + + gdouble moved_y = p[Geom::Y] - origin[Geom::Y]; + + if (state & GDK_MOD1_MASK) { + // adjust divergence by vertical drag, relative to rad + if (spiral->rad > 0) { + double exp_delta = 0.1*moved_y/(spiral->rad); // arbitrary multiplier to slow it down + spiral->exp += exp_delta; + if (spiral->exp < 1e-3) + spiral->exp = 1e-3; + } + } else { + // roll/unroll from inside + gdouble arg_t0; + spiral->getPolar(spiral->t0, NULL, &arg_t0); + + gdouble arg_tmp = atan2(dy, dx) - arg_t0; + gdouble arg_t0_new = arg_tmp - floor((arg_tmp+M_PI)/(2.0*M_PI))*2.0*M_PI + arg_t0; + spiral->t0 = (arg_t0_new - spiral->arg) / (2.0*M_PI*spiral->revo); + + /* round inner arg per PI/snaps, if CTRL is pressed */ + if ( ( state & GDK_CONTROL_MASK ) + && ( fabs(spiral->revo) > SP_EPSILON_2 ) + && ( snaps != 0 ) ) { + gdouble arg = 2.0*M_PI*spiral->revo*spiral->t0 + spiral->arg; + spiral->t0 = (sp_round(arg, M_PI/snaps) - spiral->arg)/(2.0*M_PI*spiral->revo); + } + + spiral->t0 = CLAMP(spiral->t0, 0.0, 0.999); + } + + (static_cast(spiral))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + +/* + * set attributes via outer (t=1) knot point: + * [default] increase/decrease revolution factor + * [control] constrain inner arg to round per PI/4 + */ +void +SpiralKnotHolderEntityOuter::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, unsigned int state) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + int snaps = prefs->getInt("/options/rotationsnapsperpi/value", 12); + + SPSpiral *spiral = SP_SPIRAL(item); + + gdouble dx = p[Geom::X] - spiral->cx; + gdouble dy = p[Geom::Y] - spiral->cy; + + if (state & GDK_SHIFT_MASK) { // rotate without roll/unroll + spiral->arg = atan2(dy, dx) - 2.0*M_PI*spiral->revo; + if (!(state & GDK_MOD1_MASK)) { + // if alt not pressed, change also rad; otherwise it is locked + spiral->rad = MAX(hypot(dx, dy), 0.001); + } + if ( ( state & GDK_CONTROL_MASK ) + && snaps ) { + spiral->arg = sp_round(spiral->arg, M_PI/snaps); + } + } else { // roll/unroll + // arg of the spiral outer end + double arg_1; + spiral->getPolar(1, NULL, &arg_1); + + // its fractional part after the whole turns are subtracted + double arg_r = arg_1 - sp_round(arg_1, 2.0*M_PI); + + // arg of the mouse point relative to spiral center + double mouse_angle = atan2(dy, dx); + if (mouse_angle < 0) + mouse_angle += 2*M_PI; + + // snap if ctrl + if ( ( state & GDK_CONTROL_MASK ) && snaps ) { + mouse_angle = sp_round(mouse_angle, M_PI/snaps); + } + + // by how much we want to rotate the outer point + double diff = mouse_angle - arg_r; + if (diff > M_PI) + diff -= 2*M_PI; + else if (diff < -M_PI) + diff += 2*M_PI; + + // calculate the new rad; + // the value of t corresponding to the angle arg_1 + diff: + double t_temp = ((arg_1 + diff) - spiral->arg)/(2*M_PI*spiral->revo); + // the rad at that t: + double rad_new = 0; + if (t_temp > spiral->t0) + spiral->getPolar(t_temp, &rad_new, NULL); + + // change the revo (converting diff from radians to the number of turns) + spiral->revo += diff/(2*M_PI); + if (spiral->revo < 1e-3) + spiral->revo = 1e-3; + + // if alt not pressed and the values are sane, change the rad + if (!(state & GDK_MOD1_MASK) && rad_new > 1e-3 && rad_new/spiral->rad < 2) { + // adjust t0 too so that the inner point stays unmoved + double r0; + spiral->getPolar(spiral->t0, &r0, NULL); + spiral->rad = rad_new; + spiral->t0 = pow(r0 / spiral->rad, 1.0/spiral->exp); + } + if (!IS_FINITE(spiral->t0)) spiral->t0 = 0.0; + spiral->t0 = CLAMP(spiral->t0, 0.0, 0.999); + } + + (static_cast(spiral))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + +Geom::Point +SpiralKnotHolderEntityInner::knot_get() const +{ + SPSpiral const *spiral = SP_SPIRAL(item); + + return spiral->getXY(spiral->t0); +} + +Geom::Point +SpiralKnotHolderEntityOuter::knot_get() const +{ + SPSpiral const *spiral = SP_SPIRAL(item); + + return spiral->getXY(1.0); +} + +void +SpiralKnotHolderEntityInner::knot_click(unsigned int state) +{ + SPSpiral *spiral = SP_SPIRAL(item); + + if (state & GDK_MOD1_MASK) { + spiral->exp = 1; + (static_cast(spiral))->updateRepr(); + } else if (state & GDK_SHIFT_MASK) { + spiral->t0 = 0; + (static_cast(spiral))->updateRepr(); + } +} + +SpiralKnotHolder::SpiralKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler) : + KnotHolder(desktop, item, relhandler) +{ + SpiralKnotHolderEntityInner *entity_inner = new SpiralKnotHolderEntityInner(); + SpiralKnotHolderEntityOuter *entity_outer = new SpiralKnotHolderEntityOuter(); + + entity_inner->create(desktop, item, this, Inkscape::CTRL_TYPE_SHAPER, + _("Roll/unroll the spiral from inside; with Ctrl to snap angle; " + "with Alt to converge/diverge")); + + entity_outer->create(desktop, item, this, Inkscape::CTRL_TYPE_SHAPER, + _("Roll/unroll the spiral from outside; with Ctrl to snap angle; " + "with Shift to scale/rotate; with Alt to lock radius")); + + entity.push_back(entity_inner); + entity.push_back(entity_outer); + + add_pattern_knotholder(); +} + +/* SPOffset */ + +class OffsetKnotHolderEntity : public KnotHolderEntity { +public: + virtual Geom::Point knot_get() const; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); +}; + +void +OffsetKnotHolderEntity::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, unsigned int /*state*/) +{ + SPOffset *offset = SP_OFFSET(item); + + offset->rad = sp_offset_distance_to_original(offset, p); + offset->knot = p; + offset->knotSet = true; + + (static_cast(offset))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + + +Geom::Point +OffsetKnotHolderEntity::knot_get() const +{ + SPOffset const *offset = SP_OFFSET(item); + + Geom::Point np; + sp_offset_top_point(offset,&np); + return np; +} + +OffsetKnotHolder::OffsetKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler) : + KnotHolder(desktop, item, relhandler) +{ + OffsetKnotHolderEntity *entity_offset = new OffsetKnotHolderEntity(); + entity_offset->create(desktop, item, this, Inkscape::CTRL_TYPE_SHAPER, + _("Adjust the offset distance")); + entity.push_back(entity_offset); + + add_pattern_knotholder(); +} + +// TODO: this is derived from RectKnotHolderEntityWH because it used the same static function +// set_internal as the latter before KnotHolderEntity was C++ified. Check whether this also makes +// sense logically. +class FlowtextKnotHolderEntity : public RectKnotHolderEntityWH { +public: + virtual Geom::Point knot_get() const; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); +}; + +Geom::Point +FlowtextKnotHolderEntity::knot_get() const +{ + SPRect const *rect = SP_RECT(item); + + return Geom::Point(rect->x.computed + rect->width.computed, rect->y.computed + rect->height.computed); +} + +void +FlowtextKnotHolderEntity::knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state) +{ + set_internal(p, origin, state); +} + +FlowtextKnotHolder::FlowtextKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler) : + KnotHolder(desktop, item, relhandler) +{ + g_assert(item != NULL); + + FlowtextKnotHolderEntity *entity_flowtext = new FlowtextKnotHolderEntity(); + entity_flowtext->create(desktop, item, this, Inkscape::CTRL_TYPE_SHAPER, + _("Drag to resize the flowed text frame")); + entity.push_back(entity_flowtext); +} + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/object-edit.h b/src/ui/object-edit.h new file mode 100644 index 000000000..75f3ce12b --- /dev/null +++ b/src/ui/object-edit.h @@ -0,0 +1,84 @@ +#ifndef OBJECT_EDIT_H_SEEN +#define OBJECT_EDIT_H_SEEN + +/* + * Node editing extension to objects + * + * Authors: + * Lauris Kaplinski + * Mitsuru Oka + * Jon A. Cruz + * + * Licensed under GNU GPL + */ + +#include "knotholder.h" + +namespace Inkscape { +namespace UI { + +KnotHolder *createKnotHolder(SPItem *item, SPDesktop *desktop); + +} +} + +class RectKnotHolder : public KnotHolder { +public: + RectKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler); + virtual ~RectKnotHolder() {}; +}; + +class Box3DKnotHolder : public KnotHolder { +public: + Box3DKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler); + virtual ~Box3DKnotHolder() {}; +}; + +class ArcKnotHolder : public KnotHolder { +public: + ArcKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler); + virtual ~ArcKnotHolder() {}; +}; + +class StarKnotHolder : public KnotHolder { +public: + StarKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler); + virtual ~StarKnotHolder() {}; +}; + +class SpiralKnotHolder : public KnotHolder { +public: + SpiralKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler); + virtual ~SpiralKnotHolder() {}; +}; + +class OffsetKnotHolder : public KnotHolder { +public: + OffsetKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler); + virtual ~OffsetKnotHolder() {}; +}; + +class FlowtextKnotHolder : public KnotHolder { +public: + FlowtextKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler); + virtual ~FlowtextKnotHolder() {}; +}; + +class MiscKnotHolder : public KnotHolder { +public: + MiscKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler); + virtual ~MiscKnotHolder() {}; +}; + +#endif // OBJECT_EDIT_H_SEEN + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/shape-editor.cpp b/src/ui/shape-editor.cpp new file mode 100644 index 000000000..0b9fc24c5 --- /dev/null +++ b/src/ui/shape-editor.cpp @@ -0,0 +1,177 @@ +/* + * Inkscape::ShapeEditor + * + * Authors: + * bulia byak + * Krzysztof KosiƄski + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include "desktop-handles.h" +#include "document.h" +#include "gc-anchored.h" +#include "knotholder.h" +#include "ui/object-edit.h" +#include "sp-item.h" +#include "sp-object.h" +#include "ui/shape-editor.h" +#include "xml/node-event-vector.h" + +//using Inkscape::createKnotHolder; + +namespace Inkscape { +namespace UI { + +bool ShapeEditor::_blockSetItem = false; + +ShapeEditor::ShapeEditor(SPDesktop *dt) { + this->desktop = dt; + this->knotholder = NULL; + this->knotholder_listener_attached_for = NULL; +} + +ShapeEditor::~ShapeEditor() { + unset_item(); +} + +void ShapeEditor::unset_item(bool keep_knotholder) { + if (this->knotholder) { + Inkscape::XML::Node *old_repr = this->knotholder->repr; + if (old_repr && old_repr == knotholder_listener_attached_for) { + sp_repr_remove_listener_by_data(old_repr, this); + Inkscape::GC::release(old_repr); + knotholder_listener_attached_for = NULL; + } + + if (!keep_knotholder) { + delete this->knotholder; + this->knotholder = NULL; + } + } +} + +bool ShapeEditor::has_knotholder() { + return this->knotholder != NULL; +} + +void ShapeEditor::update_knotholder() { + if (this->knotholder) + this->knotholder->update_knots(); +} + +bool ShapeEditor::has_local_change() { + return (this->knotholder && this->knotholder->local_change != 0); +} + +void ShapeEditor::decrement_local_change() { + if (this->knotholder) { + this->knotholder->local_change = FALSE; + } +} + +const SPItem *ShapeEditor::get_item() { + const SPItem *item = NULL; + if (this->has_knotholder()) { + item = this->knotholder->getItem(); + } + return item; +} + +void ShapeEditor::event_attr_changed(Inkscape::XML::Node *, gchar const *name, gchar const *, gchar const *, bool, void *data) +{ + g_assert(data); + ShapeEditor *sh = static_cast(data); + bool changed_kh = false; + + if (sh->has_knotholder()) + { + changed_kh = !sh->has_local_change(); + sh->decrement_local_change(); + if (changed_kh) { + // this can happen if an LPEItem's knotholder handle was dragged, in which case we want + // to keep the knotholder; in all other cases (e.g., if the LPE itself changes) we delete it + sh->reset_item(!strcmp(name, "d")); + } + } +} + +static Inkscape::XML::NodeEventVector shapeeditor_repr_events = { + NULL, /* child_added */ + NULL, /* child_removed */ + ShapeEditor::event_attr_changed, + NULL, /* content_changed */ + NULL /* order_changed */ +}; + + +void ShapeEditor::set_item(SPItem *item, bool keep_knotholder) { + if (_blockSetItem) { + return; + } + + // this happens (and should only happen) when for an LPEItem having both knotholder and + // nodepath the knotholder is adapted; in this case we don't want to delete the knotholder + // since this freezes the handles + unset_item(keep_knotholder); + + if (item) { + Inkscape::XML::Node *repr; + if (!this->knotholder) { + // only recreate knotholder if none is present + this->knotholder = createKnotHolder(item, desktop); + } + if (this->knotholder) { + this->knotholder->update_knots(); + // setting new listener + repr = this->knotholder->repr; + if (repr != knotholder_listener_attached_for) { + Inkscape::GC::anchor(repr); + sp_repr_add_listener(repr, &shapeeditor_repr_events, this); + knotholder_listener_attached_for = repr; + } + } + } +} + + +/** FIXME: This thing is only called when the item needs to be updated in response to repr change. + Why not make a reload function in KnotHolder? */ +void ShapeEditor::reset_item(bool keep_knotholder) +{ + if (knotholder) { + SPObject *obj = sp_desktop_document(desktop)->getObjectByRepr(knotholder_listener_attached_for); /// note that it is not certain that this is an SPItem; it could be a LivePathEffectObject. + set_item(SP_ITEM(obj), keep_knotholder); + } +} + +/** + * Returns true if this ShapeEditor has a knot above which the mouse currently hovers. + */ +bool ShapeEditor::knot_mouseover() const { + if (this->knotholder) { + return knotholder->knot_mouseover(); + } + + return false; +} + +} // namespace UI +} // namespace Inkscape + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/ui/shape-editor.h b/src/ui/shape-editor.h new file mode 100644 index 000000000..142a2493b --- /dev/null +++ b/src/ui/shape-editor.h @@ -0,0 +1,71 @@ +#ifndef SEEN_SHAPE_EDITOR_H +#define SEEN_SHAPE_EDITOR_H + +/* + * Inkscape::ShapeEditor + * + * This is a container class which contains a knotholder for shapes. + * It is attached to a single item. + * + * Authors: + * bulia byak + * + */ + +class KnotHolder; +class LivePathEffectObject; +class SPDesktop; +class SPItem; + +namespace Inkscape { namespace XML { class Node; } +namespace UI { + +class ShapeEditor { +public: + + ShapeEditor(SPDesktop *desktop); + ~ShapeEditor(); + + void set_item(SPItem *item, bool keep_knotholder = false); + void unset_item(bool keep_knotholder = false); + + void update_knotholder(); //((deprecated)) + + bool has_local_change(); + void decrement_local_change(); + + bool knot_mouseover() const; + + static void blockSetItem(bool b) { _blockSetItem = b; } // kludge + + static void event_attr_changed(Inkscape::XML::Node * /*repr*/, char const *name, char const * /*old_value*/, + char const * /*new_value*/, bool /*is_interactive*/, void *data); +private: + bool has_knotholder(); + void reset_item (bool keep_knotholder = true); + const SPItem *get_item(); + + static bool _blockSetItem; + + SPDesktop *desktop; + KnotHolder *knotholder; + Inkscape::XML::Node *knotholder_listener_attached_for; +}; + +} // namespace UI +} // namespace Inkscape + +#endif // SEEN_SHAPE_EDITOR_H + + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : + diff --git a/src/ui/tool-factory.h b/src/ui/tool-factory.h new file mode 100644 index 000000000..726706732 --- /dev/null +++ b/src/ui/tool-factory.h @@ -0,0 +1,40 @@ +/** @file + * Factory for ToolBase tree + *//* + * Authors: + * Markus Engel + * + * Copyright (C) 2013 Authors + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef TOOL_FACTORY_SEEN +#define TOOL_FACTORY_SEEN + +#include "factory.h" + +namespace Inkscape { +namespace UI { +namespace Tools { + +class ToolBase; + +} +} +} + +typedef Singleton< Factory > ToolFactory; + + +#endif + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 5d6e96588..4abc901d2 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -28,7 +28,7 @@ #include "ui/tool/node.h" #include "ui/tool/path-manipulator.h" #include "ui/tools/node-tool.h" -#include "tools-switch.h" +#include "ui/tools-switch.h" #include #include diff --git a/src/ui/tools-switch.cpp b/src/ui/tools-switch.cpp new file mode 100644 index 000000000..048252788 --- /dev/null +++ b/src/ui/tools-switch.cpp @@ -0,0 +1,196 @@ +/* + * Utility functions for switching tools (= contexts) + * + * Authors: + * bulia byak + * Josh Andler + * + * Copyright (C) 2003-2007 authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include // prevents deprecation warnings + +#include +#include + +#include "inkscape-private.h" +#include "desktop.h" +#include "desktop-handles.h" +#include + +#include + +#include "ui/tools-switch.h" + +#include "box3d.h" +#include "sp-ellipse.h" +#include "sp-flowtext.h" +#include "sp-offset.h" +#include "sp-path.h" +#include "sp-rect.h" +#include "sp-star.h" +#include "sp-spiral.h" +#include "sp-text.h" + +// TODO: How many of these are actually needed? +#include "ui/tools/arc-tool.h" +#include "ui/tools/box3d-tool.h" +#include "ui/tools/calligraphic-tool.h" +#include "ui/tools/connector-tool.h" +#include "ui/tools/dropper-tool.h" +#include "ui/tools/eraser-tool.h" +#include "ui/tools/flood-tool.h" +#include "ui/tools/gradient-tool.h" +#include "ui/tools/lpe-tool.h" +#include "ui/tools/measure-tool.h" +#include "ui/tools/mesh-tool.h" +#include "ui/tools/node-tool.h" +#include "ui/tools/pen-tool.h" +#include "ui/tools/pencil-tool.h" +#include "ui/tools/rect-tool.h" +#include "ui/tools/select-tool.h" +#include "ui/tools/spiral-tool.h" +#include "ui/tools/spray-tool.h" +#include "ui/tools/text-tool.h" +#include "ui/tools/tweak-tool.h" +#include "ui/tools/zoom-tool.h" + +#include "message-context.h" + +static char const *const tool_names[] = { + NULL, + "/tools/select", + "/tools/nodes", + "/tools/tweak", + "/tools/spray", + "/tools/shapes/rect", + "/tools/shapes/3dbox", + "/tools/shapes/arc", + "/tools/shapes/star", + "/tools/shapes/spiral", + "/tools/freehand/pencil", + "/tools/freehand/pen", + "/tools/calligraphic", + "/tools/text", + "/tools/gradient", + "/tools/mesh", + "/tools/zoom", + "/tools/measure", + "/tools/dropper", + "/tools/connector", + "/tools/paintbucket", + "/tools/eraser", + "/tools/lpetool", + NULL +}; + +// TODO: HEY! these belong to the tools themselves! +static char const *const tool_msg[] = { + NULL, + N_("Click to Select and Transform objects, Drag to select many objects."), + N_("Modify selected path points (nodes) directly."), + N_("To tweak a path by pushing, select it and drag over it."), + N_("Drag, click or click and scroll to spray the selected objects."), + N_("Drag to create a rectangle. Drag controls to round corners and resize. Click to select."), + N_("Drag to create a 3D box. Drag controls to resize in perspective. Click to select (with Ctrl+Alt for single faces)."), + N_("Drag to create an ellipse. Drag controls to make an arc or segment. Click to select."), + N_("Drag to create a star. Drag controls to edit the star shape. Click to select."), + N_("Drag to create a spiral. Drag controls to edit the spiral shape. Click to select."), + N_("Drag to create a freehand line. Shift appends to selected path, Alt activates sketch mode."), + N_("Click or click and drag to start a path; with Shift to append to selected path. Ctrl+click to create single dots (straight line modes only)."), + N_("Drag to draw a calligraphic stroke; with Ctrl to track a guide path. Arrow keys adjust width (left/right) and angle (up/down)."), + N_("Click to select or create text, drag to create flowed text; then type."), + N_("Drag or double click to create a gradient on selected objects, drag handles to adjust gradients."), + N_("Drag or double click to create a mesh on selected objects, drag handles to adjust meshes."), + N_("Click or drag around an area to zoom in, Shift+click to zoom out."), + N_("Drag to measure the dimensions of objects."), + N_("Click to set fill, Shift+click to set stroke; drag to average color in area; with Alt to pick inverse color; Ctrl+C to copy the color under mouse to clipboard"), + N_("Click and drag between shapes to create a connector."), + N_("Click to paint a bounded area, Shift+click to union the new fill with the current selection, Ctrl+click to change the clicked object's fill and stroke to the current setting."), + N_("Drag to erase."), + N_("Choose a subtool from the toolbar"), +}; + +static int +tools_prefpath2num(char const *id) +{ + int i = 1; + while (tool_names[i]) { + if (strcmp(tool_names[i], id) == 0) + return i; + else i++; + } + g_assert( 0 == TOOLS_INVALID ); + return 0; //nothing found +} + +int +tools_isactive(SPDesktop *dt, unsigned num) +{ + g_assert( num < G_N_ELEMENTS(tool_names) ); + if (SP_IS_EVENT_CONTEXT(dt->event_context)) + return dt->event_context->pref_observer->observed_path == tool_names[num]; + else return FALSE; +} + +int +tools_active(SPDesktop *dt) +{ + return tools_prefpath2num(dt->event_context->pref_observer->observed_path.data()); +} + +void +tools_switch(SPDesktop *dt, int num) +{ + dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, gettext( tool_msg[num] ) ); + if (dt) { + // This event may change the above message + dt->_tool_changed.emit(num); + } + + dt->set_event_context2(tool_names[num]); + /* fixme: This is really ugly hack. We should bind and unbind class methods */ + /* First 4 tools use guides, first is undefined but we don't care */ + dt->activate_guides(num < 5); + inkscape_eventcontext_set(dt->getEventContext()); +} + +void tools_switch_by_item(SPDesktop *dt, SPItem *item, Geom::Point const p) +{ + if (SP_IS_RECT(item)) { + tools_switch(dt, TOOLS_SHAPES_RECT); + } else if (SP_IS_BOX3D(item)) { + tools_switch(dt, TOOLS_SHAPES_3DBOX); + } else if (SP_IS_GENERICELLIPSE(item)) { + tools_switch(dt, TOOLS_SHAPES_ARC); + } else if (SP_IS_STAR(item)) { + tools_switch(dt, TOOLS_SHAPES_STAR); + } else if (SP_IS_SPIRAL(item)) { + tools_switch(dt, TOOLS_SHAPES_SPIRAL); + } else if (SP_IS_PATH(item)) { + if (Inkscape::UI::Tools::cc_item_is_connector(item)) { + tools_switch(dt, TOOLS_CONNECTOR); + } + else { + tools_switch(dt, TOOLS_NODES); + } + } else if (SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item)) { + tools_switch(dt, TOOLS_TEXT); + sp_text_context_place_cursor_at (SP_TEXT_CONTEXT(dt->event_context), SP_OBJECT(item), p); + } else if (SP_IS_OFFSET(item)) { + tools_switch(dt, TOOLS_NODES); + } +} + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/tools-switch.h b/src/ui/tools-switch.h new file mode 100644 index 000000000..280837e87 --- /dev/null +++ b/src/ui/tools-switch.h @@ -0,0 +1,64 @@ +/* + * Utility functions for switching tools (= contexts) + * + * Authors: + * bulia byak + * + * Copyright (C) 2003 authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef SEEN_TOOLS_SWITCH_H +#define SEEN_TOOLS_SWITCH_H + +class SPDesktop; +class SPItem; +namespace Geom { +class Point; +} + + +enum { + TOOLS_INVALID, + TOOLS_SELECT, + TOOLS_NODES, + TOOLS_TWEAK, + TOOLS_SPRAY, + TOOLS_SHAPES_RECT, + TOOLS_SHAPES_3DBOX, + TOOLS_SHAPES_ARC, + TOOLS_SHAPES_STAR, + TOOLS_SHAPES_SPIRAL, + TOOLS_FREEHAND_PENCIL, + TOOLS_FREEHAND_PEN, + TOOLS_CALLIGRAPHIC, + TOOLS_TEXT, + TOOLS_GRADIENT, + TOOLS_MESH, + TOOLS_ZOOM, + TOOLS_MEASURE, + TOOLS_DROPPER, + TOOLS_CONNECTOR, + TOOLS_PAINTBUCKET, + TOOLS_ERASER, + TOOLS_LPETOOL +}; + +int tools_isactive(SPDesktop *dt, unsigned num); +int tools_active(SPDesktop *dt); +void tools_switch(SPDesktop *dt, int num); +void tools_switch_by_item (SPDesktop *dt, SPItem *item, Geom::Point const p); + +#endif // !SEEN_TOOLS_SWITCH_H + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/ui/tools/arc-tool.cpp b/src/ui/tools/arc-tool.cpp index 9fd68f1b9..4f64ade25 100644 --- a/src/ui/tools/arc-tool.cpp +++ b/src/ui/tools/arc-tool.cpp @@ -40,7 +40,7 @@ #include "desktop-style.h" #include "context-fns.h" #include "verbs.h" -#include "shape-editor.h" +#include "ui/shape-editor.h" #include "ui/tools/tool-base.h" #include "ui/tools/arc-tool.h" @@ -48,7 +48,7 @@ using Inkscape::DocumentUndo; -#include "tool-factory.h" +#include "ui/tool-factory.h" namespace Inkscape { namespace UI { diff --git a/src/ui/tools/box3d-tool.cpp b/src/ui/tools/box3d-tool.cpp index b998267c2..0a20a0842 100644 --- a/src/ui/tools/box3d-tool.cpp +++ b/src/ui/tools/box3d-tool.cpp @@ -47,12 +47,12 @@ #include "box3d-side.h" #include "document-private.h" #include "line-geometry.h" -#include "shape-editor.h" +#include "ui/shape-editor.h" #include "verbs.h" using Inkscape::DocumentUndo; -#include "tool-factory.h" +#include "ui/tool-factory.h" namespace Inkscape { namespace UI { diff --git a/src/ui/tools/calligraphic-tool.cpp b/src/ui/tools/calligraphic-tool.cpp index 64097e834..d297fe5e1 100644 --- a/src/ui/tools/calligraphic-tool.cpp +++ b/src/ui/tools/calligraphic-tool.cpp @@ -82,7 +82,7 @@ using Inkscape::DocumentUndo; #define DYNA_MIN_WIDTH 1.0e-6 -#include "tool-factory.h" +#include "ui/tool-factory.h" namespace Inkscape { namespace UI { diff --git a/src/ui/tools/connector-tool.cpp b/src/ui/tools/connector-tool.cpp index d1355e807..7b5c84c16 100644 --- a/src/ui/tools/connector-tool.cpp +++ b/src/ui/tools/connector-tool.cpp @@ -109,7 +109,7 @@ using Inkscape::DocumentUndo; -#include "tool-factory.h" +#include "ui/tool-factory.h" namespace Inkscape { namespace UI { diff --git a/src/ui/tools/dropper-tool.cpp b/src/ui/tools/dropper-tool.cpp index 99d42a211..6c55f7484 100644 --- a/src/ui/tools/dropper-tool.cpp +++ b/src/ui/tools/dropper-tool.cpp @@ -52,7 +52,7 @@ using Inkscape::DocumentUndo; static GdkCursor *cursor_dropper_fill = NULL; static GdkCursor *cursor_dropper_stroke = NULL; -#include "tool-factory.h" +#include "ui/tool-factory.h" namespace Inkscape { namespace UI { diff --git a/src/ui/tools/eraser-tool.cpp b/src/ui/tools/eraser-tool.cpp index 4106785e7..bf4015b4c 100644 --- a/src/ui/tools/eraser-tool.cpp +++ b/src/ui/tools/eraser-tool.cpp @@ -84,7 +84,7 @@ using Inkscape::DocumentUndo; #define DRAG_DEFAULT 1.0 #define DRAG_MAX 1.0 -#include "tool-factory.h" +#include "ui/tool-factory.h" namespace Inkscape { namespace UI { diff --git a/src/ui/tools/flood-tool.cpp b/src/ui/tools/flood-tool.cpp index 3fb56b2ad..5745fc9cc 100644 --- a/src/ui/tools/flood-tool.cpp +++ b/src/ui/tools/flood-tool.cpp @@ -50,7 +50,7 @@ #include "preferences.h" #include "rubberband.h" #include "selection.h" -#include "shape-editor.h" +#include "ui/shape-editor.h" #include "sp-defs.h" #include "sp-item.h" #include "splivarot.h" @@ -74,7 +74,7 @@ using Inkscape::Display::ExtractARGB32; using Inkscape::Display::ExtractRGB32; using Inkscape::Display::AssembleARGB32; -#include "tool-factory.h" +#include "ui/tool-factory.h" namespace Inkscape { namespace UI { diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 46ab53eef..6434c30d2 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -30,7 +30,7 @@ #include "desktop-handles.h" #include "desktop-style.h" #include "document.h" -#include "draw-anchor.h" +#include "ui/draw-anchor.h" #include "macros.h" #include "message-stack.h" #include "ui/tools/pen-tool.h" diff --git a/src/ui/tools/gradient-tool.cpp b/src/ui/tools/gradient-tool.cpp index 4f9a7b59b..9c853917e 100644 --- a/src/ui/tools/gradient-tool.cpp +++ b/src/ui/tools/gradient-tool.cpp @@ -51,7 +51,7 @@ using Inkscape::DocumentUndo; -#include "tool-factory.h" +#include "ui/tool-factory.h" namespace Inkscape { namespace UI { diff --git a/src/ui/tools/lpe-tool.cpp b/src/ui/tools/lpe-tool.cpp index e9b9421f1..1fd1ebf8c 100644 --- a/src/ui/tools/lpe-tool.cpp +++ b/src/ui/tools/lpe-tool.cpp @@ -28,7 +28,7 @@ #include "desktop.h" #include "message-context.h" #include "preferences.h" -#include "shape-editor.h" +#include "ui/shape-editor.h" #include "selection.h" #include "desktop-handles.h" #include "document.h" @@ -59,7 +59,7 @@ SubtoolEntry lpesubtools[] = { }; -#include "tool-factory.h" +#include "ui/tool-factory.h" namespace Inkscape { namespace UI { diff --git a/src/ui/tools/measure-tool.cpp b/src/ui/tools/measure-tool.cpp index feeb68288..6b5cbeccd 100644 --- a/src/ui/tools/measure-tool.cpp +++ b/src/ui/tools/measure-tool.cpp @@ -49,7 +49,7 @@ using Inkscape::ControlManager; using Inkscape::CTLINE_SECONDARY; using Inkscape::Util::unit_table; -#include "tool-factory.h" +#include "ui/tool-factory.h" namespace Inkscape { namespace UI { diff --git a/src/ui/tools/mesh-tool.cpp b/src/ui/tools/mesh-tool.cpp index 7d6d3bc23..8a1fb7c72 100644 --- a/src/ui/tools/mesh-tool.cpp +++ b/src/ui/tools/mesh-tool.cpp @@ -53,7 +53,7 @@ using Inkscape::DocumentUndo; -#include "tool-factory.h" +#include "ui/tool-factory.h" namespace Inkscape { namespace UI { diff --git a/src/ui/tools/node-tool.cpp b/src/ui/tools/node-tool.cpp index 0b98bacc1..e2bb85d11 100644 --- a/src/ui/tools/node-tool.cpp +++ b/src/ui/tools/node-tool.cpp @@ -23,7 +23,7 @@ #include "live_effects/lpeobject.h" #include "message-context.h" #include "selection.h" -#include "shape-editor.h" // temporary! +#include "ui/shape-editor.h" // temporary! #include "live_effects/effect.h" #include "display/curve.h" #include "sp-clippath.h" @@ -107,7 +107,7 @@ using Inkscape::ControlManager; -#include "tool-factory.h" +#include "ui/tool-factory.h" namespace Inkscape { namespace UI { diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index 2c5ffc182..92937a135 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -26,7 +26,7 @@ #include "desktop-handles.h" #include "selection.h" #include "selection-chemistry.h" -#include "draw-anchor.h" +#include "ui/draw-anchor.h" #include "message-stack.h" #include "message-context.h" #include "preferences.h" @@ -40,7 +40,7 @@ #include #include "macros.h" #include "context-fns.h" -#include "tools-switch.h" +#include "ui/tools-switch.h" #include "ui/control-manager.h" // we include the necessary files for BSpline & Spiro #include "live_effects/effect.h" @@ -70,7 +70,7 @@ #include "live_effects/lpe-bspline.h" #include <2geom/nearest-point.h> -#include "tool-factory.h" +#include "ui/tool-factory.h" #include "live_effects/effect.h" diff --git a/src/ui/tools/pencil-tool.cpp b/src/ui/tools/pencil-tool.cpp index ca6dffc12..3ea2ae843 100644 --- a/src/ui/tools/pencil-tool.cpp +++ b/src/ui/tools/pencil-tool.cpp @@ -23,7 +23,7 @@ #include "desktop-handles.h" #include "selection.h" #include "selection-chemistry.h" -#include "draw-anchor.h" +#include "ui/draw-anchor.h" #include "message-stack.h" #include "message-context.h" #include "sp-path.h" @@ -43,7 +43,7 @@ #include "display/sp-canvas.h" #include "display/curve.h" #include "livarot/Path.h" -#include "tool-factory.h" +#include "ui/tool-factory.h" #include "ui/tool/event-utils.h" namespace Inkscape { diff --git a/src/ui/tools/rect-tool.cpp b/src/ui/tools/rect-tool.cpp index 819671dd6..de91dcff4 100644 --- a/src/ui/tools/rect-tool.cpp +++ b/src/ui/tools/rect-tool.cpp @@ -40,13 +40,13 @@ #include "xml/node-event-vector.h" #include "preferences.h" #include "context-fns.h" -#include "shape-editor.h" +#include "ui/shape-editor.h" #include "verbs.h" #include "display/sp-canvas-item.h" using Inkscape::DocumentUndo; -#include "tool-factory.h" +#include "ui/tool-factory.h" namespace Inkscape { namespace UI { diff --git a/src/ui/tools/select-tool.cpp b/src/ui/tools/select-tool.cpp index 83bef17c9..394b0b369 100644 --- a/src/ui/tools/select-tool.cpp +++ b/src/ui/tools/select-tool.cpp @@ -41,7 +41,7 @@ #include "desktop-handles.h" #include "sp-root.h" #include "preferences.h" -#include "tools-switch.h" +#include "ui/tools-switch.h" #include "message-stack.h" #include "selection-describer.h" #include "seltrans.h" @@ -49,7 +49,7 @@ #include "display/sp-canvas.h" #include "display/sp-canvas-item.h" #include "display/drawing-item.h" -#include "tool-factory.h" +#include "ui/tool-factory.h" using Inkscape::DocumentUndo; diff --git a/src/ui/tools/spiral-tool.cpp b/src/ui/tools/spiral-tool.cpp index 83712457a..18c3e4e2d 100644 --- a/src/ui/tools/spiral-tool.cpp +++ b/src/ui/tools/spiral-tool.cpp @@ -39,13 +39,13 @@ #include "xml/node-event-vector.h" #include "preferences.h" #include "context-fns.h" -#include "shape-editor.h" +#include "ui/shape-editor.h" #include "verbs.h" #include "display/sp-canvas-item.h" using Inkscape::DocumentUndo; -#include "tool-factory.h" +#include "ui/tool-factory.h" namespace Inkscape { namespace UI { diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index 29f1b9a73..933da6fb1 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -84,7 +84,7 @@ using namespace std; // Please enable again when working on 1.0 #define ENABLE_SPRAY_MODE_SINGLE_PATH -#include "tool-factory.h" +#include "ui/tool-factory.h" namespace Inkscape { namespace UI { diff --git a/src/ui/tools/star-tool.cpp b/src/ui/tools/star-tool.cpp index ed28c0a8d..7604ba04e 100644 --- a/src/ui/tools/star-tool.cpp +++ b/src/ui/tools/star-tool.cpp @@ -41,7 +41,7 @@ #include "xml/repr.h" #include "xml/node-event-vector.h" #include "context-fns.h" -#include "shape-editor.h" +#include "ui/shape-editor.h" #include "verbs.h" #include "display/sp-canvas-item.h" @@ -49,7 +49,7 @@ using Inkscape::DocumentUndo; -#include "tool-factory.h" +#include "ui/tool-factory.h" namespace Inkscape { namespace UI { diff --git a/src/ui/tools/text-tool.cpp b/src/ui/tools/text-tool.cpp index b60a39e5d..a72748733 100644 --- a/src/ui/tools/text-tool.cpp +++ b/src/ui/tools/text-tool.cpp @@ -40,7 +40,7 @@ #include "rubberband.h" #include "selection-chemistry.h" #include "selection.h" -#include "shape-editor.h" +#include "ui/shape-editor.h" #include "sp-flowtext.h" #include "sp-namedview.h" #include "sp-text.h" @@ -52,7 +52,7 @@ #include "xml/node-event-vector.h" #include "xml/repr.h" #include -#include "tool-factory.h" +#include "ui/tool-factory.h" using Inkscape::ControlManager; using Inkscape::DocumentUndo; diff --git a/src/ui/tools/tool-base.cpp b/src/ui/tools/tool-base.cpp index 150e899ce..37ca5eeea 100644 --- a/src/ui/tools/tool-base.cpp +++ b/src/ui/tools/tool-base.cpp @@ -46,7 +46,7 @@ #include "selection.h" #include "ui/interface.h" #include "macros.h" -#include "tools-switch.h" +#include "ui/tools-switch.h" #include "preferences.h" #include "message-context.h" #include "gradient-drag.h" @@ -55,7 +55,7 @@ #include "selcue.h" #include "ui/tools/lpe-tool.h" #include "ui/tool/control-point.h" -#include "shape-editor.h" +#include "ui/shape-editor.h" #include "sp-guide.h" #include "color.h" #include "knot.h" diff --git a/src/ui/tools/tool-base.h b/src/ui/tools/tool-base.h index b27de9030..7a6ab83e7 100644 --- a/src/ui/tools/tool-base.h +++ b/src/ui/tools/tool-base.h @@ -30,7 +30,6 @@ namespace Glib { class GrDrag; class SPDesktop; class SPItem; -class ShapeEditor; namespace Inkscape { class MessageContext; @@ -42,6 +41,9 @@ namespace Inkscape { namespace Inkscape { namespace UI { + +class ShapeEditor; + namespace Tools { class ToolBase; diff --git a/src/ui/tools/tweak-tool.cpp b/src/ui/tools/tweak-tool.cpp index 75650d3af..340f64a0b 100644 --- a/src/ui/tools/tweak-tool.cpp +++ b/src/ui/tools/tweak-tool.cpp @@ -91,7 +91,7 @@ using Inkscape::DocumentUndo; #define DYNA_MIN_WIDTH 1.0e-6 -#include "tool-factory.h" +#include "ui/tool-factory.h" namespace Inkscape { namespace UI { diff --git a/src/ui/tools/zoom-tool.cpp b/src/ui/tools/zoom-tool.cpp index 9f99cfe2e..b3fb78c8f 100644 --- a/src/ui/tools/zoom-tool.cpp +++ b/src/ui/tools/zoom-tool.cpp @@ -25,7 +25,7 @@ #include "selection-chemistry.h" #include "ui/tools/zoom-tool.h" -#include "tool-factory.h" +#include "ui/tool-factory.h" namespace Inkscape { namespace UI { diff --git a/src/vanishing-point.cpp b/src/vanishing-point.cpp index bb6a2c4d7..d1c8083de 100644 --- a/src/vanishing-point.cpp +++ b/src/vanishing-point.cpp @@ -22,7 +22,7 @@ #include "ui/tools/tool-base.h" #include "xml/repr.h" #include "perspective-line.h" -#include "shape-editor.h" +#include "ui/shape-editor.h" #include "snap.h" #include "sp-namedview.h" #include "ui/control-manager.h" diff --git a/src/verbs.cpp b/src/verbs.cpp index ea4c336d7..580883646 100644 --- a/src/verbs.cpp +++ b/src/verbs.cpp @@ -62,7 +62,7 @@ #include "ui/tools/select-tool.h" #include "selection-chemistry.h" #include "seltrans.h" -#include "shape-editor.h" +#include "ui/shape-editor.h" #include "shortcuts.h" #include "sp-defs.h" #include "sp-flowtext.h" @@ -70,7 +70,7 @@ #include "splivarot.h" #include "sp-namedview.h" #include "text-chemistry.h" -#include "tools-switch.h" +#include "ui/tools-switch.h" #include "ui/dialog/align-and-distribute.h" #include "ui/dialog/clonetiler.h" #include "ui/dialog/dialog-manager.h" diff --git a/src/widgets/lpe-toolbar.cpp b/src/widgets/lpe-toolbar.cpp index 485a4289d..a85f3ae78 100644 --- a/src/widgets/lpe-toolbar.cpp +++ b/src/widgets/lpe-toolbar.cpp @@ -41,7 +41,7 @@ #include "preferences.h" #include "selection.h" #include "sp-namedview.h" -#include "tools-switch.h" +#include "ui/tools-switch.h" #include "ui/tools/lpe-tool.h" #include "ui/widget/unit-tracker.h" #include "util/units.h" diff --git a/src/widgets/pencil-toolbar.cpp b/src/widgets/pencil-toolbar.cpp index c387d9f78..f44229fec 100644 --- a/src/widgets/pencil-toolbar.cpp +++ b/src/widgets/pencil-toolbar.cpp @@ -38,7 +38,7 @@ #include "widgets/ink-action.h" #include "preferences.h" #include "toolbox.h" -#include "tools-switch.h" +#include "ui/tools-switch.h" #include "ui/icon-names.h" #include "ui/tools/pen-tool.h" #include "ui/uxmanager.h" diff --git a/src/widgets/sp-color-notebook.cpp b/src/widgets/sp-color-notebook.cpp index 87cb7cae3..c7fa96efd 100644 --- a/src/widgets/sp-color-notebook.cpp +++ b/src/widgets/sp-color-notebook.cpp @@ -38,7 +38,7 @@ #include "../profile-manager.h" #include "color-profile.h" #include "cms-system.h" -#include "tools-switch.h" +#include "ui/tools-switch.h" #include "ui/tools/tool-base.h" using Inkscape::CMSSystem; diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index 45aa01dd1..9e55d1cf6 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -56,7 +56,7 @@ #include "ui/interface.h" #include "../shortcuts.h" #include "../sp-namedview.h" -#include "../tools-switch.h" +#include "ui/tools-switch.h" #include "../ui/icon-names.h" #include "../ui/widget/style-swatch.h" #include "../verbs.h" -- cgit v1.2.3