From 3b71de9544251424939afd68214587c4e5c51328 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrg=20Lehni?= Date: Thu, 17 Mar 2016 14:15:28 +0100 Subject: [PATCH] Fix #980: Implement visual selection of item.position --- src/basic/Point.js | 34 ++++++++++++++++++++++++++++++---- src/basic/Rectangle.js | 16 ++++++++++++---- src/item/Item.js | 31 ++++++++++++++++++++++++++----- src/item/ItemSelection.js | 2 +- src/path/Curve.js | 2 +- 5 files changed, 70 insertions(+), 15 deletions(-) diff --git a/src/basic/Point.js b/src/basic/Point.js index f959d4a3..78781a06 100644 --- a/src/basic/Point.js +++ b/src/basic/Point.js @@ -782,12 +782,22 @@ var Point = Base.extend(/** @lends Point# */{ }, /** - * This property is only present if the point is an anchor or control point - * of a {@link Segment} or a {@link Curve}. In this case, it returns - * {@true if it is selected} + * This property is only valid if the point is an anchor or handle point + * of a {@link Segment} or a {@link Curve}, or the position of an + * {@link Item}, as returned by {@link Item#position}, + * {@link Segment#point}, {@link Segment#handleIn}, + * {@link Segment#handleOut}, {@link Curve#point1}, {@link Curve#point2}, + * {@link Curve#handle1}, {@link Curve#handle2}. + * + * In those cases, it returns {@true if it the point is selected}. + * + * Paper.js renders selected points on top of your project. This is very + * useful when debugging. * * @name Point#selected * @property + * @type Boolean + * @default false * * @example {@paperscript} * var path = new Path.Circle({ @@ -797,6 +807,10 @@ var Point = Base.extend(/** @lends Point# */{ * * // Select the third segment point: * path.segments[2].point.selected = true; + * + * // Select the item's position, which is the pivot point + * // around which it is trasnformed: + * path.position.selected = true; */ /** @@ -971,7 +985,7 @@ var Point = Base.extend(/** @lends Point# */{ * through setting itself again on the setter that corresponds to the getter * that produced this LinkedPoint. * - * @ignore + * @private */ var LinkedPoint = Point.extend({ // Have LinkedPoint appear as a normal Point in debugging @@ -1006,5 +1020,17 @@ var LinkedPoint = Point.extend({ setY: function(y) { this._y = y; this._owner[this._setter](this); + }, + + isSelected: function() { + return !!(this._owner._selection & this._getSelection()); + }, + + setSelected: function(selected) { + this._owner.changeSelection(this._getSelection(), selected); + }, + + _getSelection: function() { + return this._setter === 'setPosition' ? /*#=*/ItemSelection.POSITION : 0; } }); diff --git a/src/basic/Rectangle.js b/src/basic/Rectangle.js index e46be966..d37c44d4 100644 --- a/src/basic/Rectangle.js +++ b/src/basic/Rectangle.js @@ -893,15 +893,23 @@ new function() { /** * {@grouptitle Item Bounds} * - * Specifies whether an item's bounds are selected and will also - * mark the item as selected. + * Specifies whether an item's bounds are to appear as selected. * - * Paper.js draws the visual bounds of selected items on top of your - * project. This can be useful for debugging. + * Paper.js draws the bounds of items with selected bounds on top of + * your project. This is very useful when debugging. * * @bean * @type Boolean * @default false + * + * @example {@paperscript} + * var path = new Path.Circle({ + * center: [80, 50], + * radius: 40, + * selected: true + * }); + * + * path.bounds.selected = true; */ isSelected: function() { return !!(this._owner._selection & /*#=*/ItemSelection.BOUNDS); diff --git a/src/item/Item.js b/src/item/Item.js index 6c504de9..d4bd4d55 100644 --- a/src/item/Item.js +++ b/src/item/Item.js @@ -4255,23 +4255,44 @@ new function() { // Injection scope for hit-test functions shared with project var selection = this._selection, itemSelected = selection & /*#=*/ItemSelection.ITEM, boundsSelected = selection & /*#=*/ItemSelection.BOUNDS - || itemSelected && this._selectBounds; + || itemSelected && this._selectBounds, + positionSelected = selection & /*#=*/ItemSelection.POSITION; if (!this._drawSelected) itemSelected = false; - if ((itemSelected || boundsSelected) && this._isUpdated(updateVersion)) { + if ((itemSelected || boundsSelected || positionSelected) + && this._isUpdated(updateVersion)) { // Allow definition of selected color on a per item and per // layer level, with a fallback to #009dec var layer, color = this.getSelectedColor(true) || (layer = this.getLayer()) && layer.getSelectedColor(true), - mx = matrix.appended(this.getGlobalMatrix(true)); + mx = matrix.appended(this.getGlobalMatrix(true)), + half = size / 2; ctx.strokeStyle = ctx.fillStyle = color ? color.toCanvasStyle(ctx) : '#009dec'; if (itemSelected) this._drawSelected(ctx, mx, selectionItems); + if (positionSelected) { + var point = this.getPosition(true), + x = point.x, + y = point.y; + ctx.beginPath(); + ctx.arc(x, y, half, 0, Math.PI * 2, true); + ctx.stroke(); + var deltas = [[0, -1], [1, 0], [0, 1], [-1, 0]], + start = half, + end = size + 1; + for (var i = 0; i < 4; i++) { + var delta = deltas[i], + dx = delta[0], + dy = delta[1]; + ctx.moveTo(x + dx * start, y + dy * start); + ctx.lineTo(x + dx * end, y + dy * end); + ctx.stroke(); + } + } if (boundsSelected) { - var half = size / 2, - coords = mx._transformCorners(this.getInternalBounds()); + var coords = mx._transformCorners(this.getInternalBounds()); // Now draw a rectangle that connects the transformed // bounds corners, and draw the corners. ctx.beginPath(); diff --git a/src/item/ItemSelection.js b/src/item/ItemSelection.js index 7878e4f2..94d75180 100644 --- a/src/item/ItemSelection.js +++ b/src/item/ItemSelection.js @@ -13,5 +13,5 @@ var ItemSelection = { ITEM: 1, BOUNDS: 2, - PIVOT: 4 + POSITION: 4 }; diff --git a/src/path/Curve.js b/src/path/Curve.js index 5adb3ead..b911c245 100644 --- a/src/path/Curve.js +++ b/src/path/Curve.js @@ -868,7 +868,7 @@ statics: /** @lends Curve */{ */ /** - * The rough bounding rectangle of the curve that is shure to include all of + * The rough bounding rectangle of the curve that is sure to include all of * the drawing, including stroke width. * * @name Curve#roughBounds