loleaflet/css/leaflet.css             |   47 +++---
 loleaflet/images/tabstop-center.svg   |   68 ++++++++
 loleaflet/images/tabstop-decimal.svg  |   76 +++++++++
 loleaflet/images/tabstop-left.svg     |   68 ++++++++
 loleaflet/images/tabstop-right.svg    |   68 ++++++++
 loleaflet/src/control/Ruler.js        |  263 ++++++++++++++++++++++------------
 loleaflet/src/layer/tile/TileLayer.js |    9 +
 7 files changed, 494 insertions(+), 105 deletions(-)

New commits:
commit 63b423b004d11b268f220edf8ac94e9f23d5cec4
Author:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
AuthorDate: Tue Apr 14 08:02:22 2020 +0200
Commit:     Tomaž Vajngerl <qui...@gmail.com>
CommitDate: Tue Apr 14 20:36:11 2020 +0200

    change tabstop handling on the ruler, add markers, use Hammer.js
    
    This changes handling of tabstops on the ruler:
    
    * Tabstops are now updated from the 'tabstoplistupdate'.
    * For touch handling we now use Hammer.js so it is easier to handle
    with.
    * Markers for different types are added as SVG's.
    * Rework handling and calculating positions to be much simpler and
    logical (no additions of positions, which can cause rounding
    errors).
    * Use .uno:ChangeTabStop to send tabstop changes.
    
    Change-Id: I966dfa2c17652ab74e3fd8912622cf6c951e514d
    Reviewed-on: https://gerrit.libreoffice.org/c/online/+/92142
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Tomaž Vajngerl <qui...@gmail.com>

diff --git a/loleaflet/css/leaflet.css b/loleaflet/css/leaflet.css
index 7caea9340..10b892599 100644
--- a/loleaflet/css/leaflet.css
+++ b/loleaflet/css/leaflet.css
@@ -874,23 +874,36 @@ input.clipboard {
        line-height: 7px;
        }
 
-/* A triangle pointing up */
-.loleaflet-ruler-tabstop {
-       width: 0;
-       height: 0;
-       vertical-align: bottom;
-       display: inline-block;
-       /* So that we hardcode this in just one place */
-       --loleaflet-ruler-tabstop-border: 8;
-       border-top: calc(var(--loleaflet-ruler-tabstop-border) * 1px) solid 
transparent;
-       border-left: calc(var(--loleaflet-ruler-tabstop-border) * 1px) solid 
transparent;
-       /* Offset the left border with left margin to make this really take 
zero horizontal space until the JS code bumps the marginLeft */
-       margin-left: calc(-1 * var(--loleaflet-ruler-tabstop-border) * 1px);
-       border-right: calc(var(--loleaflet-ruler-tabstop-border) * 1px) solid 
transparent;
-       /* Ditto for the right border, this is left as is */
-       margin-right: calc(-1 * var(--loleaflet-ruler-tabstop-border) * 1px);
-       border-bottom: calc(var(--loleaflet-ruler-tabstop-border) * 1px) solid 
black;
-       margin-bottom: calc(-1 * var(--loleaflet-ruler-tabstop-border) * 1px / 
2);
+.loleaflet-ruler-tabstop-left {
+       width: 20px;
+       height: 20px;
+       background: url(images/tabstop-left.svg);
+       position: absolute;
+       pointer-events: none;
+}
+
+.loleaflet-ruler-tabstop-right {
+       width: 20px;
+       height: 20px;
+       background: url(images/tabstop-right.svg);
+       position: absolute;
+       pointer-events: none;
+}
+
+.loleaflet-ruler-tabstop-center {
+       width: 20px;
+       height: 20px;
+       background: url(images/tabstop-center.svg);
+       position: absolute;
+       pointer-events: none;
+}
+
+.loleaflet-ruler-tabstop-decimal {
+       width: 20px;
+       height: 20px;
+       background: url(images/tabstop-decimal.svg);
+       position: absolute;
+       pointer-events: none;
 }
 
 .loleaflet-ruler-margin {
diff --git a/loleaflet/images/tabstop-center.svg 
b/loleaflet/images/tabstop-center.svg
new file mode 100644
index 000000000..5f1589dd3
--- /dev/null
+++ b/loleaflet/images/tabstop-center.svg
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   inkscape:version="1.0beta2 (unknown)"
+   sodipodi:docname="tabstop-center.svg"
+   viewBox="0 0 20 20"
+   id="svg2"
+   version="1.1"
+   width="20"
+   height="20">
+  <sodipodi:namedview
+     inkscape:current-layer="svg2"
+     inkscape:window-maximized="1"
+     inkscape:window-y="0"
+     inkscape:window-x="0"
+     inkscape:cy="12"
+     inkscape:cx="-0.91636364"
+     inkscape:zoom="11.458333"
+     showgrid="false"
+     id="namedview7"
+     inkscape:window-height="1016"
+     inkscape:window-width="1920"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0"
+     guidetolerance="10"
+     gridtolerance="10"
+     objecttolerance="10"
+     borderopacity="1"
+     inkscape:document-rotation="0"
+     bordercolor="#666666"
+     pagecolor="#ffffff" />
+  <metadata
+     id="metadata14">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs12" />
+  <rect
+     
style="opacity:1;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2.27089;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+     id="rect832"
+     width="0.72911173"
+     height="5.7291126"
+     x="-10.364556"
+     y="-18.864557"
+     transform="scale(-1)" />
+  <rect
+     transform="scale(-1)"
+     y="-18.743774"
+     x="-15.243774"
+     height="0.48754406"
+     width="10.487544"
+     id="rect832-3"
+     
style="opacity:1;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2.51246;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
 />
+</svg>
diff --git a/loleaflet/images/tabstop-decimal.svg 
b/loleaflet/images/tabstop-decimal.svg
new file mode 100644
index 000000000..5d33d5f32
--- /dev/null
+++ b/loleaflet/images/tabstop-decimal.svg
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   inkscape:version="1.0beta2 (unknown)"
+   sodipodi:docname="tabstop-decimal.svg"
+   viewBox="0 0 20 20"
+   id="svg2"
+   version="1.1"
+   width="20"
+   height="20">
+  <sodipodi:namedview
+     inkscape:current-layer="svg2"
+     inkscape:window-maximized="1"
+     inkscape:window-y="0"
+     inkscape:window-x="0"
+     inkscape:cy="80.18446"
+     inkscape:cx="248.90804"
+     inkscape:zoom="1.7047764"
+     showgrid="false"
+     id="namedview7"
+     inkscape:window-height="1016"
+     inkscape:window-width="1920"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0"
+     guidetolerance="10"
+     gridtolerance="10"
+     objecttolerance="10"
+     borderopacity="1"
+     inkscape:document-rotation="0"
+     bordercolor="#666666"
+     pagecolor="#ffffff" />
+  <metadata
+     id="metadata14">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs12" />
+  <rect
+     
style="opacity:1;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2.27089;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+     id="rect832"
+     width="0.72911173"
+     height="5.7291126"
+     x="-10.364556"
+     y="-18.864557"
+     transform="scale(-1)" />
+  <rect
+     transform="scale(-1)"
+     y="-18.743774"
+     x="-15.243774"
+     height="0.48754406"
+     width="10.487544"
+     id="rect832-3"
+     
style="opacity:1;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2.51246;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
 />
+  <rect
+     transform="scale(-1)"
+     y="-14.210526"
+     x="-15.210529"
+     height="1.4210552"
+     width="1.4210594"
+     id="rect832-36"
+     
style="opacity:1;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.57894;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
 />
+</svg>
diff --git a/loleaflet/images/tabstop-left.svg 
b/loleaflet/images/tabstop-left.svg
new file mode 100644
index 000000000..af68e7910
--- /dev/null
+++ b/loleaflet/images/tabstop-left.svg
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   height="20"
+   width="20"
+   version="1.1"
+   id="svg2"
+   viewBox="0 0 20 20"
+   sodipodi:docname="tabstop-left.svg"
+   inkscape:version="1.0beta2 (unknown)">
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     inkscape:document-rotation="0"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1920"
+     inkscape:window-height="1016"
+     id="namedview7"
+     showgrid="false"
+     inkscape:zoom="14.921205"
+     inkscape:cx="1.9068354"
+     inkscape:cy="10.267514"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg2" />
+  <metadata
+     id="metadata14">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs12" />
+  <rect
+     transform="scale(-1)"
+     y="-18.864557"
+     x="-11.864556"
+     height="5.7291126"
+     width="0.72911173"
+     id="rect832"
+     
style="opacity:1;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2.27089;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
 />
+  <rect
+     
style="opacity:1;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2.27089;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+     id="rect832-3"
+     width="5.7291102"
+     height="0.72911251"
+     x="-16.864555"
+     y="-18.864557"
+     transform="scale(-1)" />
+</svg>
diff --git a/loleaflet/images/tabstop-right.svg 
b/loleaflet/images/tabstop-right.svg
new file mode 100644
index 000000000..aa97e816c
--- /dev/null
+++ b/loleaflet/images/tabstop-right.svg
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   height="20"
+   width="20"
+   version="1.1"
+   id="svg2"
+   viewBox="0 0 20 20"
+   sodipodi:docname="tabstop-right.svg"
+   inkscape:version="1.0beta2 (unknown)">
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     inkscape:document-rotation="0"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1920"
+     inkscape:window-height="1016"
+     id="namedview7"
+     showgrid="false"
+     inkscape:zoom="19.899592"
+     inkscape:cx="6.1936276"
+     inkscape:cy="12.830904"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg2" />
+  <metadata
+     id="metadata14">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs12" />
+  <rect
+     transform="scale(-1)"
+     y="-18.864557"
+     x="-8.8645563"
+     height="5.7291126"
+     width="0.72911173"
+     id="rect832"
+     
style="opacity:1;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2.27089;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
 />
+  <rect
+     
style="opacity:1;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2.27089;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+     id="rect832-3"
+     width="5.7291102"
+     height="0.72911251"
+     x="-8.8645554"
+     y="-18.864557"
+     transform="scale(-1)" />
+</svg>
diff --git a/loleaflet/src/control/Ruler.js b/loleaflet/src/control/Ruler.js
index 292e4d2b2..73dbcb8ac 100644
--- a/loleaflet/src/control/Ruler.js
+++ b/loleaflet/src/control/Ruler.js
@@ -3,7 +3,7 @@
  * Ruler Handler
  */
 
-/* global $ L _ */
+/* global $ L _ Hammer */
 L.Control.Ruler = L.Control.extend({
        options: {
                interactive: true,
@@ -24,6 +24,7 @@ L.Control.Ruler = L.Control.extend({
 
        onAdd: function(map) {
                map.on('rulerupdate', this._updateOptions, this);
+               map.on('tabstoplistupdate', this._updateTabStops, this);
                map.on('docsize', this._updatePaintTimer, this);
                map.on('scrolloffset resize', this._fixOffset, this);
                map.on('updatepermission', this._changeInteractions, this);
@@ -73,12 +74,23 @@ L.Control.Ruler = L.Control.extend({
 
                // Tab stops
                this._rTSContainer = L.DomUtil.create('div', 
'loleaflet-ruler-tabstopcontainer', this._rMarginWrapper);
-               if (window.ThisIsTheiOSApp)
-                       L.DomEvent.on(this._rTSContainer, 'touchstart', 
this._initiateTabstopDrag, this);
-               else
-                       L.DomEvent.on(this._rTSContainer, 'mousedown', 
this._initiateTabstopDrag, this);
-
-
+               L.DomEvent.on(this._rTSContainer, 'mousedown', 
this._initiateTabstopDrag, this);
+
+               var self = this;
+
+               if (L.Browser.touch) {
+                       this._hammer = new Hammer(this._rTSContainer);
+                       this._hammer.add(new Hammer.Pan({ threshold: 0, 
pointers: 0 }));
+                       this._hammer.on('panstart', function (event) {
+                               self._initiateTabstopDrag(event);
+                       });
+                       this._hammer.on('panmove', function (event) {
+                               self._moveTabstop(event);
+                       });
+                       this._hammer.on('panend', function (event) {
+                               self._endTabstopDrag(event);
+                       });
+               }
                return this._rWrapper;
        },
 
@@ -96,17 +108,28 @@ L.Control.Ruler = L.Control.extend({
 
                // pageWidth on the other hand *is* really in mm100.
                this.options.pageWidth = parseInt(obj['pageWidth']);
-               this.options.tabs = [];
-               // As are the position values of the elements in the tabs array.
-               for (var i in obj['tabs']) {
-                       this.options.tabs[i] = { position: 
parseInt(obj['tabs'][i].position), style: parseInt(obj['tabs'][i].style) };
-               }
+
                // to be enabled only after adding support for other length 
units as well
                // this.options.unit = obj['unit'].trim();
 
                this._updateBreakPoints();
        },
 
+       _updateTabStops: function(obj) {
+               this.options.tabs = [];
+               var jsonTabstops = obj['tabstops'];
+               if (jsonTabstops === '')
+                       return;
+               for (var i in jsonTabstops) {
+                       var jsonTabstop = jsonTabstops[i];
+                       this.options.tabs[i] = {
+                               position: parseInt(jsonTabstop.position),
+                               style: parseInt(jsonTabstop.type)
+                       };
+               }
+               this._updateBreakPoints();
+       },
+
        _updateBreakPoints: function() {
 
                if (this.options.margin1 == null || this.options.margin2 == 
null)
@@ -167,22 +190,41 @@ L.Control.Ruler = L.Control.extend({
                // The tabstops. Only draw user-created ones, with style 
RULER_TAB_LEFT,
                // RULER_TAB_RIGHT, RULER_TAB_CENTER, and RULER_TAB_DECIMAL. 
See <svtools/ruler.hxx>.
 
-               $('.loleaflet-ruler-tabstop').remove();
+               $('.loleaflet-ruler-tabstop-left').remove();
+               $('.loleaflet-ruler-tabstop-right').remove();
+               $('.loleaflet-ruler-tabstop-center').remove();
+               $('.loleaflet-ruler-tabstop-decimal').remove();
 
                var pxPerMm100 = this._map._docLayer._docPixelSize.x / 
(this._map._docLayer._docWidthTwips * 2540/1440);
-               var tabStopWidthAccum = 0;
                this._rTSContainer.tabStops = [];
-               for (num = 0; num < this.options.tabs.length; num++) {
-                       if (this.options.tabs[num].style >= 4)
+               for (var tabstopIndex = 0; tabstopIndex < 
this.options.tabs.length; tabstopIndex++) {
+                       var markerClass = null;
+                       var currentTabstop = this.options.tabs[tabstopIndex];
+                       switch (currentTabstop.style) {
+                       case 0:
+                               markerClass = 'loleaflet-ruler-tabstop-left';
+                               break;
+                       case 1:
+                               markerClass = 'loleaflet-ruler-tabstop-right';
+                               break;
+                       case 2:
+                               markerClass = 'loleaflet-ruler-tabstop-center';
                                break;
-                       marker = L.DomUtil.create('div', 
'loleaflet-ruler-tabstop', this._rTSContainer);
-                       var thisWidth = this.options.tabs[num].position - 
tabStopWidthAccum;
-                       var tabstopBorder = getComputedStyle(marker, 
null).getPropertyValue('--loleaflet-ruler-tabstop-border');
-                       marker.style.marginLeft = (pxPerMm100 * thisWidth - 
tabstopBorder) + 'px';
-                       marker.tabStopNumber = num;
-                       marker.tabStopLocation = { left: pxPerMm100 * 
tabStopWidthAccum, right: pxPerMm100 * (tabStopWidthAccum + thisWidth) };
-                       this._rTSContainer.tabStops[num] = marker;
-                       tabStopWidthAccum += thisWidth;
+                       case 3:
+                               markerClass = 'loleaflet-ruler-tabstop-decimal';
+                               break;
+                       }
+                       if (markerClass != null) {
+                               marker = L.DomUtil.create('div', markerClass, 
this._rTSContainer);
+                               var positionPixel = currentTabstop.position * 
pxPerMm100;
+                               var markerWidth = marker.offsetWidth;
+                               var markerHalfWidth = markerWidth / 2.0;
+                               marker.tabStopLocation = { left: positionPixel 
- markerHalfWidth, center: positionPixel, right: positionPixel + 
markerHalfWidth };
+                               marker.style.left = marker.tabStopLocation.left 
+ 'px';
+                               marker.tabStopNumber = tabstopIndex;
+                               this._rTSContainer.tabStops[tabstopIndex] = 
marker;
+                               marker.style.cursor = 'move';
+                       }
                }
 
                if (!this.options.marginSet) {
@@ -281,48 +323,6 @@ L.Control.Ruler = L.Control.extend({
                }
        },
 
-       _initiateTabstopDrag: function(e) {
-               // console.log('===> _initiateTabstopDrag');
-               if (e.type === 'touchstart') {
-                       if (e.touches.length !== 1)
-                               return;
-               }
-
-               // Are there any tab stops?
-               // e.currentTarget == this._rTSContainer, so yeah, we could use 
that, too.
-               if (!e.currentTarget || e.currentTarget.tabStops.length === 0)
-                       return;
-
-               // Check if "close enough" to one unambiguous tab stop
-               var closestIndex = -1;
-               var closestDistance = 1000000;
-               var nextClosestDistance;
-               for (var i = 0; i < e.currentTarget.tabStops.length; i++) {
-                       var distance = Math.abs(e.layerX - 
e.currentTarget.tabStops[i].tabStopLocation.right);
-                       if (distance < closestDistance) {
-                               nextClosestDistance = closestDistance;
-                               closestDistance = distance;
-                               closestIndex = i;
-                       }
-               }
-               if (nextClosestDistance - closestDistance <= 10) {
-                       // Nope, not clear which one it was closest to
-                       return;
-               }
-
-               e.currentTarget.tabStopBeingDragged = closestIndex;
-               e.currentTarget.tabStopPrevPos = e.layerX;
-
-               if (window.ThisIsTheiOSApp) {
-                       L.DomEvent.on(e.currentTarget, 'touchmove', 
this._moveTabstop, this);
-                       L.DomEvent.on(e.currentTarget, 'touchend', 
this._endTabstopDrag, this);
-               }
-               else {
-                       L.DomEvent.on(e.currentTarget, 'mousemove', 
this._moveTabstop, this);
-                       L.DomEvent.on(e.currentTarget, 'mouseup', 
this._endTabstopDrag, this);
-               }
-       },
-
        _moveMargin: function(e) {
                if (e.type === 'touchmove')
                        e.clientX = e.touches[0].clientX;
@@ -347,20 +347,6 @@ L.Control.Ruler = L.Control.extend({
                }
        },
 
-       _moveTabstop: function(e) {
-               if (!e.currentTarget)
-                       return;
-
-               var pixelDiff = e.layerX - e.currentTarget.tabStopPrevPos;
-               var diff = this._map._docLayer._pixelsToTwips({x: pixelDiff, 
y:0}).x;
-               if (diff === 0)
-                       return;
-
-               // console.log('===> _moveTabstop ' + 
e.currentTarget.tabStopBeingDragged + ' pixels:' + pixelDiff + ', twips:' + 
diff);
-               this._map.sendUnoCommand('.uno:MoveTabstop?Tabstop=' + 
e.currentTarget.tabStopBeingDragged + '&Amount=' + diff);
-               e.currentTarget.tabStopPrevPos = e.layerX;
-       },
-
        _endDrag: function(e) {
                this._map.rulerActive = false;
 
@@ -400,19 +386,120 @@ L.Control.Ruler = L.Control.extend({
                this._map._socket.sendMessage('uno .uno:RulerChangeState ' + 
JSON.stringify(unoObj));
        },
 
-       _endTabstopDrag: function(e) {
-               if (!e.currentTarget)
+       _initiateTabstopDrag: function(event) {
+               // console.log('===> _initiateTabstopDrag ' + event.type);
+
+               var tabstopContainer = null;
+               var pointX = null;
+
+               if (event.type === 'panstart') {
+                       tabstopContainer = event.target;
+                       pointX = event.center.x - 
event.target.getBoundingClientRect().left;
+               }
+               else {
+                       tabstopContainer = event.currentTarget;
+                       pointX = event.layerX;
+               }
+
+               // check if we hit any tabstop
+               var tabstop = null;
+               var margin = 10;
+               var tabstopDiffFromCenter = 100000000; // just a big initial 
condition
+
+               for (var i = 0; i < tabstopContainer.tabStops.length; i++) {
+                       var current = tabstopContainer.tabStops[i];
+                       var location = current.tabStopLocation;
+                       if (pointX >= location.left - margin && pointX <= 
location.right + margin) {
+                               var diff = Math.abs(pointX - location.center);
+                               if (diff < tabstopDiffFromCenter) {
+                                       tabstop = current;
+                                       tabstopDiffFromCenter = diff;
+                               }
+                       }
+               }
+
+               if (tabstop == null) {
+                       var positionTwip = 
this._map._docLayer._pixelsToTwips({x: pointX, y:0}).x;
+                       var params = {
+                               Index: {
+                                       type : 'int32',
+                                       value : -1
+                               },
+                               Position: {
+                                       type : 'int32',
+                                       value : positionTwip
+                               }
+                       };
+                       this._map.sendUnoCommand('.uno:ChangeTabStop', params);
                        return;
+               }
 
-               // console.log('===> _endTabstopDrag ' + e.type);
-               if (window.ThisIsTheiOSApp) {
-                       L.DomEvent.off(e.currentTarget, 'touchmove', 
this._moveTabstop, this);
-                       L.DomEvent.off(e.currentTarget, 'touchend', 
this._endTabstopDrag, this);
+               tabstopContainer.tabStopMarkerBeingDragged = tabstop;
+               tabstopContainer.tabStopInitialPosiiton = pointX;
+
+               if (event.pointerType !== 'touch') {
+                       L.DomEvent.on(this._rTSContainer, 'mousemove', 
this._moveTabstop, this);
+                       L.DomEvent.on(this._rTSContainer, 'mouseup', 
this._endTabstopDrag, this);
+                       L.DomEvent.on(this._rTSContainer, 'mouseout', 
this._endTabstopDrag, this);
+               }
+       },
+
+       _moveTabstop: function(event) {
+               var tabstopContainer = null;
+               var pointX = null;
+
+               if (event.type === 'panmove') {
+                       tabstopContainer = event.target;
+                       pointX = event.center.x - 
event.target.getBoundingClientRect().left;
+               }
+               else {
+                       tabstopContainer = event.currentTarget;
+                       pointX = event.layerX;
+               }
+
+               //console.log('===> _moveTabstop ' + event.type);
+
+               var pixelDiff = pointX - 
tabstopContainer.tabStopInitialPosiiton;
+               var marker = tabstopContainer.tabStopMarkerBeingDragged;
+               marker.style.left = (marker.tabStopLocation.left + pixelDiff) + 
'px';
+       },
+
+       _endTabstopDrag: function(event) {
+               //console.log('===> _endTabstopDrag ' + event.type);
+
+               var tabstopContainer = null;
+               var pointX = null;
+               if (event.type === 'panend') {
+                       tabstopContainer = event.target;
+                       pointX = event.center.x - 
event.target.getBoundingClientRect().left;
                }
                else {
-                       L.DomEvent.off(e.currentTarget, 'mousemove', 
this._moveTabstop, this);
-                       L.DomEvent.off(e.currentTarget, 'mouseup', 
this._endTabstopDrag, this);
+                       tabstopContainer = event.currentTarget;
+                       pointX = event.layerX;
+               }
+
+               var marker = tabstopContainer.tabStopMarkerBeingDragged;
+
+               if (event.type == 'mouseout') {
+                       marker.style.left = (marker.tabStopLocation.left) + 
'px';
+               }
+               else {
+                       var positionTwip = 
this._map._docLayer._pixelsToTwips({x: pointX, y: 0}).x;
+                       var params = {
+                               Index: {
+                                       type : 'int32',
+                                       value : marker.tabStopNumber
+                               },
+                               Position: {
+                                       type : 'int32',
+                                       value : positionTwip
+                               }
+                       };
+                       this._map.sendUnoCommand('.uno:ChangeTabStop', params);
                }
+               L.DomEvent.off(this._rTSContainer, 'mousemove', 
this._moveTabstop, this);
+               L.DomEvent.off(this._rTSContainer, 'mouseup', 
this._endTabstopDrag, this);
+               L.DomEvent.off(this._rTSContainer, 'mouseout', 
this._endTabstopDrag, this);
        },
 
 });
diff --git a/loleaflet/src/layer/tile/TileLayer.js 
b/loleaflet/src/layer/tile/TileLayer.js
index 6041f845a..9bd68f421 100644
--- a/loleaflet/src/layer/tile/TileLayer.js
+++ b/loleaflet/src/layer/tile/TileLayer.js
@@ -709,6 +709,15 @@ L.TileLayer = L.GridLayer.extend({
                else if (textMsg.startsWith('calcfunctionlist:')) {
                        
this._onCalcFunctionListMsg(textMsg.substring('calcfunctionlist:'.length + 1));
                }
+               else if (textMsg.startsWith('tabstoplistupdate:')) {
+                       this._onTabStopListUpdate(textMsg);
+               }
+       },
+
+       _onTabStopListUpdate: function (textMsg) {
+               textMsg = textMsg.substring('tabstoplistupdate:'.length + 1);
+               var json = JSON.parse(textMsg);
+               this._map.fire('tabstoplistupdate', json);
        },
 
        toggleTileDebugModeImpl: function() {
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to