bundled/include/LibreOfficeKit/LibreOfficeKitEnums.h | 37 +++- loleaflet/src/layer/tile/TileLayer.js | 164 +++++++++++-------- loleaflet/src/layer/vector/Path.Drag.js | 28 +++ loleaflet/src/layer/vector/SVGGroup.js | 6 4 files changed, 166 insertions(+), 69 deletions(-)
New commits: commit 502dc97cb235a76f9c3a44a8bd7326219907e3b0 Author: Marco Cecchetti <mrcek...@gmail.com> AuthorDate: Tue Mar 26 15:19:20 2019 +0100 Commit: Marco Cecchetti <mrcek...@gmail.com> CommitDate: Mon May 20 10:40:05 2019 +0200 lok: update graphic selection callback description Change-Id: Iebc3d17ac8e81ea99dda64cd97807656f5941637 Reviewed-on: https://gerrit.libreoffice.org/70574 Reviewed-by: Marco Cecchetti <mrcek...@gmail.com> Tested-by: Marco Cecchetti <mrcek...@gmail.com> diff --git a/bundled/include/LibreOfficeKit/LibreOfficeKitEnums.h b/bundled/include/LibreOfficeKit/LibreOfficeKitEnums.h index af4952566..f3fc91b2f 100644 --- a/bundled/include/LibreOfficeKit/LibreOfficeKitEnums.h +++ b/bundled/include/LibreOfficeKit/LibreOfficeKitEnums.h @@ -162,11 +162,40 @@ typedef enum */ LOK_CALLBACK_CURSOR_VISIBLE = 5, /** - * The size and/or the position of the graphic selection changed and - * the rotation angle of the embedded graphic object + * The size and/or the position of the graphic selection changed, + * the rotation angle of the embedded graphic object, and a property list + * which can be used for informing the client about severl properties. * - * Format is "x, y, width, height, angle", where angle is in 100th - * of degree. + * Format is "x, y, width, height, angle, { list of properties }", + * where angle is in 100th of degree, and the property list is optional. + * + * The "{ list of properties }" part is in JSON format. + * Follow some examples of the property list part: + * + * 1) when the selected object is an image inserted in Writer: + * + * { "isWriterGraphic": true } + * + * 2) when the selected object is a chart legend: + * + * { "isDraggable": true, "isResizable": true, "isRotatable": false } + * + * 3) when the selected object is a pie segment in a chart: + * + * { + * "isDraggable": true, + * "isResizable": false, + * "isRotatable": false, + * "dragInfo": { + * "dragMethod": "PieSegmentDragging", + * "initialOffset": 50, + * "dragDirection": [x, y], + * "svg": "<svg ..." + * } + * } + * + * where the "svg" property is a string containing an svg document + * which is a rapresentation of the pie segment. */ LOK_CALLBACK_GRAPHIC_SELECTION = 6, commit ba4cd1563d8ecfc3749c6a512cccf6334bc31108 Author: Marco Cecchetti <mrcek...@gmail.com> AuthorDate: Wed Apr 10 23:44:35 2019 +0200 Commit: Marco Cecchetti <mrcek...@gmail.com> CommitDate: Mon May 20 10:39:52 2019 +0200 loleaflet: constrained dragging for pie segment The extra information for the graphic selection is now formatted according to JSON syntax so that is easier to parse. Dragging a pie segment now is constrained as on desktop and there is also a preview of the pie segment while it is dragged. On drag end a msg is sent to core with the new pie segment offset from the pie center, which allows core to move the pie segment to the correct position. Change-Id: I7f76d21d622006fca5d0922c5932daec50b13836 Reviewed-on: https://gerrit.libreoffice.org/70573 Reviewed-by: Marco Cecchetti <mrcek...@gmail.com> Tested-by: Marco Cecchetti <mrcek...@gmail.com> diff --git a/loleaflet/src/layer/tile/TileLayer.js b/loleaflet/src/layer/tile/TileLayer.js index 6028fe3ad..e6c4aa0af 100644 --- a/loleaflet/src/layer/tile/TileLayer.js +++ b/loleaflet/src/layer/tile/TileLayer.js @@ -643,55 +643,49 @@ L.TileLayer = L.GridLayer.extend({ }, _onGraphicSelectionMsg: function (textMsg) { - if (textMsg.match('EMPTY')) { this._graphicSelectionTwips = new L.Bounds(new L.Point(0, 0), new L.Point(0, 0)); this._graphicSelection = new L.LatLngBounds(new L.LatLng(0, 0), new L.LatLng(0, 0)); } else { - var data = textMsg.split('{'); - var strTwips = data[0].match(/\d+/g); - var topLeftTwips = new L.Point(parseInt(strTwips[0]), parseInt(strTwips[1])); - var offset = new L.Point(parseInt(strTwips[2]), parseInt(strTwips[3])); + textMsg = '[' + textMsg.substr('graphicselection:'.length) + ']'; + var msgData = JSON.parse(textMsg); + var topLeftTwips = new L.Point(msgData[0], msgData[1]); + var offset = new L.Point(msgData[2], msgData[3]); var bottomRightTwips = topLeftTwips.add(offset); this._graphicSelectionTwips = new L.Bounds(topLeftTwips, bottomRightTwips); this._graphicSelection = new L.LatLngBounds( - this._twipsToLatLng(topLeftTwips, this._map.getZoom()), - this._twipsToLatLng(bottomRightTwips, this._map.getZoom())); - this._graphicSelectionAngle = (strTwips.length > 4) ? parseInt(strTwips[4]) : 0; - this._isSelectionWriterGraphic = false; - this._isGraphicSelectionDraggable = true; - this._isGraphicSelectionResizable = true; - this._isGraphicSelectionRotatable = true; - - if (data.length > 1) { - var properties = data[1].slice(0, -1).split(','); - - var i; - for (i = 0; i < properties.length; ++i) { - var property = properties[i].split('='); - if (property.length !== 2) - continue; - var name = property[0].trim(); - var value = property[1].trim() === 'true'; - if (name === 'WriterGraphic') { - this._isSelectionWriterGraphic = value; - } - else if (name === 'Draggable') { - this._isGraphicSelectionDraggable = value; - } - else if (name === 'Resizable') { - this._isGraphicSelectionResizable = value; - } - else if (name === 'Rotatable') { - this._isGraphicSelectionRotatable = value; - } + this._twipsToLatLng(topLeftTwips, this._map.getZoom()), + this._twipsToLatLng(bottomRightTwips, this._map.getZoom())); + + this._graphicSelectionAngle = (msgData.length > 4) ? msgData[4] : 0; + + this._graphicSelection.extraInfo = {}; + if (msgData.length > 5) { + this._graphicSelection.extraInfo = msgData[5]; + var dragInfo = this._graphicSelection.extraInfo.dragInfo; + if (dragInfo && dragInfo.dragMethod === 'PieSegmentDragging') { + dragInfo.initialOffset /= 100.0; + var dragDir = dragInfo.dragDirection; + dragInfo.dragDirection = this._twipsToPixels(new L.Point(dragDir[0], dragDir[1])); + dragDir = dragInfo.dragDirection; + dragInfo.range2 = dragDir.x * dragDir.x + dragDir.y * dragDir.y; } } + + // defaults + var extraInfo = this._graphicSelection.extraInfo; + if (extraInfo.isDraggable === undefined) + extraInfo.isDraggable = true; + if (extraInfo.isResizable === undefined) + extraInfo.isResizable = true; + if (extraInfo.isRotatable === undefined) + extraInfo.isRotatable = true; + // Workaround for tdf#123874. For some reason the handling of the // shapeselectioncontent messages that we get back causes the WebKit process // to crash on iOS. - if (!window.ThisIsTheiOSApp && this._isGraphicSelectionDraggable) { + if (!window.ThisIsTheiOSApp && this._graphicSelection.extraInfo.isDraggable && !this._graphicSelection.extraInfo.svg) { this._map._socket.sendMessage('rendershapeselection mimetype=image/svg+xml'); } } @@ -1852,30 +1846,66 @@ L.TileLayer = L.GridLayer.extend({ return; } - var newPos = this._graphicSelectionTwips.min.add(deltaPos); - var size = this._graphicSelectionTwips.getSize(); + var param; + var dragConstraint = this._graphicSelection.extraInfo.dragInfo; + if (dragConstraint) { + if (dragConstraint.dragMethod === 'PieSegmentDragging') { + + deltaPos = this._twipsToPixels(deltaPos); + var dx = deltaPos.x; + var dy = deltaPos.y; + + var initialOffset = dragConstraint.initialOffset; + var dragDirection = dragConstraint.dragDirection; + var additionalOffset = (dx * dragDirection.x + dy * dragDirection.y) / dragConstraint.range2; + if (additionalOffset < -initialOffset) + additionalOffset = -initialOffset; + else if (additionalOffset > (1.0 - initialOffset)) + additionalOffset = 1.0 - initialOffset; + + var offset = Math.round((initialOffset + additionalOffset) * 100); + + // hijacking the uno:TransformDialog msg for sending the new offset value + // for the pie segment dragging method; + // indeed there isn't any uno msg dispatching on the core side, but a chart controller dispatching + param = { + Action: { + type: 'string', + value: 'PieSegmentDragging' + }, + Offset: { + type: 'long', + value: offset + } + }; + } + } + else { + var newPos = this._graphicSelectionTwips.min.add(deltaPos); + var size = this._graphicSelectionTwips.getSize(); - // try to keep shape inside document - if (newPos.x + size.x > this._docWidthTwips) - newPos.x = this._docWidthTwips - size.x; - if (newPos.x < 0) - newPos.x = 0; + // try to keep shape inside document + if (newPos.x + size.x > this._docWidthTwips) + newPos.x = this._docWidthTwips - size.x; + if (newPos.x < 0) + newPos.x = 0; - if (newPos.y + size.y > this._docHeightTwips) - newPos.y = this._docHeightTwips - size.y; - if (newPos.y < 0) - newPos.y = 0; + if (newPos.y + size.y > this._docHeightTwips) + newPos.y = this._docHeightTwips - size.y; + if (newPos.y < 0) + newPos.y = 0; - var param = { - TransformPosX: { - type: 'long', - value: newPos.x - }, - TransformPosY: { - type: 'long', - value: newPos.y - } - }; + param = { + TransformPosX: { + type: 'long', + value: newPos.x + }, + TransformPosY: { + type: 'long', + value: newPos.y + } + }; + } this._map.sendUnoCommand('.uno:TransformDialog ', param); this._graphicMarker.isDragged = false; } @@ -1963,7 +1993,9 @@ L.TileLayer = L.GridLayer.extend({ // For an image in Writer we need to send the size of the image not of the selection box. // So if the image has been rotated we need to compute its size starting from the size of the selection // rectangle and the rotation angle. - if (this._isSelectionWriterGraphic) { + var isSelectionWriterGraphic = + this._graphicSelection.extraInfo ? this._graphicSelection.extraInfo.isWriterGraphic : false; + if (isSelectionWriterGraphic) { if (this._isGraphicAngleDivisibleBy90()) { var k = this._graphicSelectionAngle / 9000; // if k is even we have nothing to do since the rotation is 0 or 180. @@ -2015,7 +2047,7 @@ L.TileLayer = L.GridLayer.extend({ this._map.sendUnoCommand('.uno:TransformDialog ', param); - if (this._isSelectionWriterGraphic) { + if (isSelectionWriterGraphic) { param = { TransformPosX: { type: 'long', @@ -2130,8 +2162,10 @@ L.TileLayer = L.GridLayer.extend({ return; } + var extraInfo = this._graphicSelection.extraInfo; this._graphicMarker = L.svgGroup(this._graphicSelection, { - draggable: this._isGraphicSelectionDraggable, + draggable: extraInfo.isDraggable, + dragConstraint: extraInfo.dragInfo, transform: true, stroke: false, fillOpacity: 0, @@ -2147,12 +2181,16 @@ L.TileLayer = L.GridLayer.extend({ this._graphicMarker.on('scalestart scaleend', this._onGraphicEdit, this); this._graphicMarker.on('rotatestart rotateend', this._onGraphicRotate, this); this._map.addLayer(this._graphicMarker); - if (this._isGraphicSelectionDraggable) + if (extraInfo.isDraggable) this._graphicMarker.dragging.enable(); this._graphicMarker.transform.enable({ - scaling: this._isGraphicSelectionResizable, - rotation: this._isGraphicSelectionRotatable, + scaling: extraInfo.isResizable, + rotation: extraInfo.isRotatable, uniformScaling: !this._isGraphicAngleDivisibleBy90()}); + if (extraInfo.dragInfo && extraInfo.dragInfo.svg) { + this._graphicMarker.removeEmbeddedSVG(); + this._graphicMarker.addEmbeddedSVG(extraInfo.dragInfo.svg); + } } else if (this._graphicMarker) { this._graphicMarker.off('graphicmovestart graphicmoveend', this._onGraphicMove, this); diff --git a/loleaflet/src/layer/vector/Path.Drag.js b/loleaflet/src/layer/vector/Path.Drag.js index 04ab67373..b35c02b98 100644 --- a/loleaflet/src/layer/vector/Path.Drag.js +++ b/loleaflet/src/layer/vector/Path.Drag.js @@ -159,6 +159,32 @@ L.Handler.PathDrag = L.Handler.extend(/** @lends L.Path.Drag.prototype */ { var dx = x - this._startPoint.x; var dy = y - this._startPoint.y; + if (isNaN(dx) || isNaN(dy)) + return; + + if (this.constraint) { + if (this.constraint.dragMethod === 'PieSegmentDragging') { + var initialOffset = this.constraint.initialOffset; + var dragDirection = this.constraint.dragDirection; + + var dsx = x - this._dragStartPoint.x; + var dsy = y - this._dragStartPoint.y; + var additionalOffset = (dsx * dragDirection.x + dsy * dragDirection.y) / this.constraint.range2; + var currentOffset = (dx * dragDirection.x + dy * dragDirection.y) / this.constraint.range2; + + if (additionalOffset < -initialOffset && currentOffset < 0) + currentOffset = 0; + else if (additionalOffset > (1.0 - initialOffset) && currentOffset > 0) + currentOffset = 0; + + dx = currentOffset * dragDirection.x; + dy = currentOffset * dragDirection.y; + + x = this._startPoint.x + dx; + y = this._startPoint.y + dy; + } + } + // Send events only if point was moved if (dx || dy) { if (!this._path._dragMoved) { @@ -367,8 +393,10 @@ var fnInitHook = function() { L.Handler.PathDrag.makeDraggable(this); this.dragging.enable(); } + this.dragging.constraint = this.options.dragConstraint; } else if (this.dragging) { this.dragging.disable(); + this.dragging.constraint = null; } }; diff --git a/loleaflet/src/layer/vector/SVGGroup.js b/loleaflet/src/layer/vector/SVGGroup.js index fb58fe528..48a1e5967 100644 --- a/loleaflet/src/layer/vector/SVGGroup.js +++ b/loleaflet/src/layer/vector/SVGGroup.js @@ -63,6 +63,7 @@ L.SVGGroup = L.Layer.extend({ L.DomEvent.on(this._dragShape, 'mousemove', this._onDrag, this); L.DomEvent.on(this._dragShape, 'mouseup', this._onDragEnd, this); + L.DomEvent.on(this._dragShape, 'mouseout', this._onDragEnd, this); L.DomEvent.on(this._dragShape, 'touchmove', this._onDrag, this); L.DomEvent.on(this._dragShape, 'touchend', this._onDragEnd, this); @@ -96,7 +97,6 @@ L.SVGGroup = L.Layer.extend({ containerPoint: this._map.mouseEventToContainerPoint(evt) }; this.dragging._onDrag(data); - }, _onDragEnd: function(evt) { @@ -107,6 +107,7 @@ L.SVGGroup = L.Layer.extend({ return; L.DomEvent.off(this._dragShape, 'mousemove', this._onDrag, this); L.DomEvent.off(this._dragShape, 'mouseup', this._onDragEnd, this); + L.DomEvent.off(this._dragShape, 'mouseout', this._onDragEnd, this); L.DomEvent.off(this._dragShape, 'touchmove', this._onDrag, this); L.DomEvent.off(this._dragShape, 'touchend', this._onDragEnd, this); @@ -116,7 +117,8 @@ L.SVGGroup = L.Layer.extend({ var pos = this._map.mouseEventToLatLng(evt); this.fire('graphicmoveend', {pos: pos}); - this.dragging._onDragEnd(evt); + if (evt.type === 'mouseup') + this.dragging._onDragEnd(evt); }, bringToFront: function () { _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits