[Libreoffice-commits] online.git: loleaflet/src
Dennis Francis (via logerrit)
logerrit at kemper.freedesktop.org
Sun Jul 5 07:58:20 UTC 2020
loleaflet/src/control/Control.ColumnHeader.js | 21 +++-
loleaflet/src/control/Control.Header.js | 30 ++++++
loleaflet/src/control/Control.RowHeader.js | 21 +++-
loleaflet/src/control/Control.Scroll.js | 4
loleaflet/src/layer/CalcGridLines.js | 15 ++-
loleaflet/src/layer/tile/CalcTileLayer.js | 112 ++++++++++++++++++++------
loleaflet/src/map/Map.js | 2
7 files changed, 160 insertions(+), 45 deletions(-)
New commits:
commit dc862d358522315c857044debf11eeceb1fc936b
Author: Dennis Francis <dennis.francis at collabora.com>
AuthorDate: Fri May 15 08:12:03 2020 +0530
Commit: Dennis Francis <dennis.francis at collabora.com>
CommitDate: Sun Jul 5 09:57:59 2020 +0200
use SheetGeometry data to draw headers/gridlines if enabled
Change-Id: If146512a50c24f5fd81f6df7e0a3746f70bf21f9
Reviewed-on: https://gerrit.libreoffice.org/c/online/+/97944
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice at gmail.com>
Reviewed-by: Dennis Francis <dennis.francis at collabora.com>
diff --git a/loleaflet/src/control/Control.ColumnHeader.js b/loleaflet/src/control/Control.ColumnHeader.js
index a2846f78e..254a4df41 100644
--- a/loleaflet/src/control/Control.ColumnHeader.js
+++ b/loleaflet/src/control/Control.ColumnHeader.js
@@ -193,7 +193,7 @@ L.Control.ColumnHeader = L.Control.Header.extend({
},
_updateColumnHeader: function () {
- this._map._docLayer.requestViewRowColumnData({x: this._map._getTopLeftPoint().x, y: 0, offset: {x: undefined, y: 0}});
+ this._map._docLayer.refreshViewData({x: this._map._getTopLeftPoint().x, y: 0, offset: {x: undefined, y: 0}});
},
drawHeaderEntry: function (entry, isOver, isHighlighted, isCurrent) {
@@ -376,8 +376,10 @@ L.Control.ColumnHeader = L.Control.Header.extend({
},
viewRowColumnHeaders: function (e) {
- if (e.data.columns && e.data.columns.length > 0) {
- this.fillColumns(e.data.columns, e.data.columnGroups, e.converter, e.context);
+ var dataInEvent = (e.data && e.data.columns && e.data.columns.length > 0);
+ if (dataInEvent || e.updatecolumns) {
+ dataInEvent ? this.fillColumns(e.data.columns, e.data.columnGroups, e.converter, e.context) :
+ this.fillColumns(undefined, undefined, e.converter, e.context);
this._onUpdateCurrentColumn(e.cursor);
if (e.selection && e.selection.hasSelection) {
this._onUpdateSelection(e.selection);
@@ -389,7 +391,7 @@ L.Control.ColumnHeader = L.Control.Header.extend({
},
fillColumns: function (columns, colGroups, converter, context) {
- if (columns.length < 2)
+ if (columns && columns.length < 2)
return;
var canvas = this._canvas;
@@ -413,21 +415,28 @@ L.Control.ColumnHeader = L.Control.Header.extend({
this._lastMouseOverIndex = undefined;
}
+ var sheetGeometry = this._map._docLayer.sheetGeometry;
+ var columnsGeometry = sheetGeometry ? sheetGeometry.getColumnsGeometry() : undefined;
+
// create data structure for column widths
- this._tickMap = new L.Control.Header.GapTickMap(this._map, columns);
+ this._tickMap = new L.Control.Header.GapTickMap(this._map, columns, columnsGeometry);
this._startOffset = this._tickMap.getStartOffset();
// setup conversion routine
this.converter = L.Util.bind(converter, context);
// create group array
- this._groupLevels = parseInt(columns[0].groupLevels);
+ this._groupLevels = columns ? parseInt(columns[0].groupLevels):
+ sheetGeometry.getColumnGroupLevels();
this._groups = this._groupLevels ? new Array(this._groupLevels) : null;
// collect group controls data
if (colGroups !== undefined && this._groups) {
this._collectGroupsData(colGroups);
}
+ else if (sheetGeometry) {
+ this._collectGroupsData(sheetGeometry.getColumnGroupsDataInView());
+ }
if (this._groups) {
this.resize(this._computeOutlineWidth() + this._borderWidth + this._headerHeight);
diff --git a/loleaflet/src/control/Control.Header.js b/loleaflet/src/control/Control.Header.js
index 5aeac06da..3ef4bb2e0 100644
--- a/loleaflet/src/control/Control.Header.js
+++ b/loleaflet/src/control/Control.Header.js
@@ -804,7 +804,35 @@ L.Control.Header.colHeaderHeight = undefined;
*/
L.Control.Header.GapTickMap = L.Class.extend({
- initialize: function (map, ticks) {
+ initialize: function (map, ticks, dimensionGeometry) {
+
+ if (dimensionGeometry) {
+ // Until .uno:ViewRowColumnHeaders is not phased out, we need to live with
+ // GapTickMap datastructure to avoid an invasive refactoring.
+ // L.SheetGeometry and L.SheetDimension datastructures can directly provide
+ // position/size of any row/column intuitively without using unnecessary
+ // terminologies like (1-based) Gap and (0-based) Tick.
+ var dimrange = dimensionGeometry.getViewElementRange();
+ var start = Math.max(0, dimrange.start - 2);
+ var startData = dimensionGeometry.getElementData(start);
+ var startText = start ? start + 1 : 0;
+ var endText = Math.min(dimensionGeometry.getMaxIndex(), dimrange.end + 2) + 1;
+
+ this._minTickIdx = startText;
+ this._maxTickIdx = endText;
+ this._startOffset = start ? startData.startpos + startData.size : 0;
+ this._tilePixelScale = 1; // We already have everything in css px.
+
+ ticks = start ? [] : [0];
+ dimensionGeometry.forEachInRange(start,
+ this._maxTickIdx - 1, function (idx, data) {
+ ticks[idx + 1] = data.startpos + data.size;
+ });
+
+ this._ticks = ticks;
+
+ return;
+ }
var gapSize;
this._ticks = [];
diff --git a/loleaflet/src/control/Control.RowHeader.js b/loleaflet/src/control/Control.RowHeader.js
index afbba3c45..820f2205b 100644
--- a/loleaflet/src/control/Control.RowHeader.js
+++ b/loleaflet/src/control/Control.RowHeader.js
@@ -186,7 +186,7 @@ L.Control.RowHeader = L.Control.Header.extend({
},
_updateRowHeader: function () {
- this._map._docLayer.requestViewRowColumnData({x: 0, y: this._map._getTopLeftPoint().y, offset: {x: 0, y: undefined}});
+ this._map._docLayer.refreshViewData({x: 0, y: this._map._getTopLeftPoint().y, offset: {x: 0, y: undefined}});
},
drawHeaderEntry: function (entry, isOver, isHighlighted, isCurrent) {
@@ -365,8 +365,10 @@ L.Control.RowHeader = L.Control.Header.extend({
},
viewRowColumnHeaders: function (e) {
- if (e.data.rows && e.data.rows.length) {
- this.fillRows(e.data.rows, e.data.rowGroups, e.converter, e.context);
+ var dataInEvent = (e.data && e.data.rows && e.data.rows.length);
+ if (dataInEvent || e.updaterows) {
+ dataInEvent ? this.fillRows(e.data.rows, e.data.rowGroups, e.converter, e.context) :
+ this.fillRows(undefined, undefined, e.converter, e.context);
this._onUpdateCurrentRow(e.cursor);
if (e.selection && e.selection.hasSelection) {
this._onUpdateSelection(e.selection);
@@ -378,7 +380,7 @@ L.Control.RowHeader = L.Control.Header.extend({
},
fillRows: function (rows, rowGroups, converter, context) {
- if (rows.length < 2)
+ if (rows && rows.length < 2)
return;
var canvas = this._canvas;
@@ -394,21 +396,28 @@ L.Control.RowHeader = L.Control.Header.extend({
this._lastMouseOverIndex = undefined;
}
+ var sheetGeometry = this._map._docLayer.sheetGeometry;
+ var rowsGeometry = sheetGeometry ? sheetGeometry.getRowsGeometry() : undefined;
+
// create data structure for row heights
- this._tickMap = new L.Control.Header.GapTickMap(this._map, rows);
+ this._tickMap = new L.Control.Header.GapTickMap(this._map, rows, rowsGeometry);
this._startOffset = this._tickMap.getStartOffset();
// setup conversion routine
this.converter = L.Util.bind(converter, context);
// create group array
- this._groupLevels = parseInt(rows[0].groupLevels);
+ this._groupLevels = rows ? parseInt(rows[0].groupLevels) :
+ sheetGeometry.getRowGroupLevels();
this._groups = this._groupLevels ? new Array(this._groupLevels) : null;
// collect group controls data
if (rowGroups !== undefined && this._groups) {
this._collectGroupsData(rowGroups);
}
+ else if (sheetGeometry) {
+ this._collectGroupsData(sheetGeometry.getRowGroupsDataInView());
+ }
if (this._groups) {
this.resize(this._computeOutlineWidth() + this._borderWidth + this._headerWidth);
diff --git a/loleaflet/src/control/Control.Scroll.js b/loleaflet/src/control/Control.Scroll.js
index e3f9cf4dc..cb323e1c7 100644
--- a/loleaflet/src/control/Control.Scroll.js
+++ b/loleaflet/src/control/Control.Scroll.js
@@ -114,7 +114,7 @@ L.Control.Scroll = L.Control.extend({
return;
}
- this._map._docLayer.requestViewRowColumnData({ x: newLeft, y: newTop, offset: offset});
+ this._map._docLayer.refreshViewData({ x: newLeft, y: newTop, offset: offset});
this._prevScrollY = newTop;
this._prevScrollX = newLeft;
@@ -267,7 +267,7 @@ L.Control.Scroll = L.Control.extend({
offset.y = 1;
}
if (e.updateHeaders && this._map._docLayer._docType === 'spreadsheet') {
- this._map._docLayer.requestViewRowColumnData({x: e.x, y: e.y, offset: offset});
+ this._map._docLayer.refreshViewData({x: e.x, y: e.y, offset: offset});
}
this._map.fire('scrolloffset', offset);
this._ignoreScroll = null;
diff --git a/loleaflet/src/layer/CalcGridLines.js b/loleaflet/src/layer/CalcGridLines.js
index 4b4e58d3a..37492b606 100644
--- a/loleaflet/src/layer/CalcGridLines.js
+++ b/loleaflet/src/layer/CalcGridLines.js
@@ -78,8 +78,13 @@ L.CalcGridLines = L.LayerGroup.extend({
// into map coordinate units
var pixelToMapUnitRatio = this._map.options.crs.scale(this._map.getZoom());
- if (ev.data.columns && ev.data.columns.length) {
- ticks = new L.Control.Header.GapTickMap(this._map, ev.data.columns);
+ var colDataInEvent = ev.data && ev.data.columns && ev.data.columns.length;
+ var rowDataInEvent = ev.data && ev.data.rows && ev.data.rows.length;
+
+ if (colDataInEvent || ev.updatecolumns) {
+ var columnsData = colDataInEvent ? ev.data.columns : undefined;
+ var columnsGeometry = colDataInEvent ? undefined : this._map._docLayer.sheetGeometry.getColumnsGeometry();
+ ticks = new L.Control.Header.GapTickMap(this._map, columnsData, columnsGeometry);
this._colLines.clearLayers();
ticks.forEachTick(function(idx, pos) {
@@ -92,8 +97,10 @@ L.CalcGridLines = L.LayerGroup.extend({
}.bind(this));
}
- if (ev.data.rows && ev.data.rows.length) {
- ticks = new L.Control.Header.GapTickMap(this._map, ev.data.rows);
+ if (rowDataInEvent || ev.updaterows) {
+ var rowsData = rowDataInEvent ? ev.data.rows : undefined;
+ var rowsGeometry = rowDataInEvent ? undefined : this._map._docLayer.sheetGeometry.getRowsGeometry();
+ ticks = new L.Control.Header.GapTickMap(this._map, rowsData, rowsGeometry);
this._rowLines.clearLayers();
ticks.forEachTick(function(idx, pos) {
diff --git a/loleaflet/src/layer/tile/CalcTileLayer.js b/loleaflet/src/layer/tile/CalcTileLayer.js
index 6ed8ae4b4..2252f2116 100644
--- a/loleaflet/src/layer/tile/CalcTileLayer.js
+++ b/loleaflet/src/layer/tile/CalcTileLayer.js
@@ -5,6 +5,10 @@
/* global */
L.CalcTileLayer = L.TileLayer.extend({
+ options: {
+ sheetGeometryDataEnabled: false
+ },
+
STD_EXTRA_WIDTH: 113, /* 2mm extra for optimal width,
* 0.1986cm with TeX points,
* 0.1993cm with PS points. */
@@ -264,13 +268,16 @@ L.CalcTileLayer = L.TileLayer.extend({
}
}
} else if (textMsg.startsWith('invalidateheader: column')) {
- this.requestViewRowColumnData({x: this._map._getTopLeftPoint().x, y: 0, offset: {x: undefined, y: 0}});
+ this.refreshViewData({x: this._map._getTopLeftPoint().x, y: 0,
+ offset: {x: undefined, y: 0}}, true /* sheetGeometryChanged */);
this._map._socket.sendMessage('commandvalues command=.uno:ViewAnnotationsPosition');
} else if (textMsg.startsWith('invalidateheader: row')) {
- this.requestViewRowColumnData({x: 0, y: this._map._getTopLeftPoint().y, offset: {x: 0, y: undefined}});
+ this.refreshViewData({x: 0, y: this._map._getTopLeftPoint().y,
+ offset: {x: 0, y: undefined}}, true /* sheetGeometryChanged */);
this._map._socket.sendMessage('commandvalues command=.uno:ViewAnnotationsPosition');
} else if (textMsg.startsWith('invalidateheader: all')) {
- this.requestViewRowColumnData({x: this._map._getTopLeftPoint().x, y: this._map._getTopLeftPoint().y, offset: {x: undefined, y: undefined}});
+ this.refreshViewData({x: this._map._getTopLeftPoint().x, y: this._map._getTopLeftPoint().y,
+ offset: {x: undefined, y: undefined}}, true /* sheetGeometryChanged */);
this._map._socket.sendMessage('commandvalues command=.uno:ViewAnnotationsPosition');
} else {
L.TileLayer.prototype._onMessage.call(this, textMsg, img);
@@ -360,15 +367,17 @@ L.CalcTileLayer = L.TileLayer.extend({
if (part !== this._selectedPart && !this.isHiddenPart(part)) {
this._map.setPart(part, true);
this._map.fire('setpart', {selectedPart: this._selectedPart});
- // TODO: test it!
- this.requestViewRowColumnData();
+ this.refreshViewData(undefined, true /* sheetGeometryChanged */);
}
},
_onZoomRowColumns: function () {
this._sendClientZoom();
- // TODO: test it!
- this.requestViewRowColumnData();
+ if (this.sheetGeometry) {
+ this.sheetGeometry.setTileGeometryData(this._tileWidthTwips, this._tileHeightTwips,
+ this._tileSize, this._tilePixelScale);
+ }
+ this.refreshViewData();
this._map._socket.sendMessage('commandvalues command=.uno:ViewAnnotationsPosition');
},
@@ -454,8 +463,13 @@ L.CalcTileLayer = L.TileLayer.extend({
}
},
- // This send .uno:ViewRowColumnHeaders command to core with the new view coordinates.
- requestViewRowColumnData: function (coordinatesData) {
+ // This initiates a selective repainting of row/col headers and
+ // gridlines based on the settings of coordinatesData.offset. This
+ // should be called whenever the view area changes (scrolling, panning,
+ // zooming, cursor moving out of view-area etc.). Depending on the
+ // active sheet geometry data-source, it may ask core to send current
+ // view area's data or the global data on geometry changes.
+ refreshViewData: function (coordinatesData, sheetGeometryChanged) {
// There are places that call this function with no arguments to indicate that the
// command arguments should be the current map area coordinates.
@@ -475,32 +489,57 @@ L.CalcTileLayer = L.TileLayer.extend({
topLeftPoint.y = this._map._getTopLeftPoint().y;
}
+ var updateRows = true;
+ var updateCols = true;
+
if (offset.x === 0) {
- topLeftPoint.x = -1;
- sizePx.x = 0;
+ updateCols = false;
+ if (!this.options.sheetGeometryDataEnabled) {
+ topLeftPoint.x = -1;
+ sizePx.x = 0;
+ }
}
if (offset.y === 0) {
- topLeftPoint.y = -1;
- sizePx.y = 0;
+ updateRows = false;
+ if (!this.options.sheetGeometryDataEnabled) {
+ topLeftPoint.y = -1;
+ sizePx.y = 0;
+ }
}
var pos = this._pixelsToTwips(topLeftPoint);
var size = this._pixelsToTwips(sizePx);
- var payload = 'commandvalues command=.uno:ViewRowColumnHeaders?x=' + Math.round(pos.x) + '&y=' + Math.round(pos.y) +
- '&width=' + Math.round(size.x) + '&height=' + Math.round(size.y);
- if (coordinatesData.outline) {
- payload += '&columnOutline=' + coordinatesData.outline.column + '&groupLevel=' + coordinatesData.outline.level
- + '&groupIndex=' + coordinatesData.outline.index + '&groupHidden=' + coordinatesData.outline.hidden;
+ if (!this.options.sheetGeometryDataEnabled) {
+ this.requestViewRowColumnData(pos, size);
+ return;
+ }
+
+ if (sheetGeometryChanged || !this.sheetGeometry) {
+ this.requestSheetGeometryData(
+ {columns: updateCols, rows: updateRows});
+ return;
}
+ this.sheetGeometry.setViewArea(pos, size);
+ this._updateHeadersGridLines(undefined, updateCols, updateRows);
+ },
+
+ // This send .uno:ViewRowColumnHeaders command to core with the new view coordinates (tile-twips).
+ requestViewRowColumnData: function (pos, size) {
+
+ var payload = 'commandvalues command=.uno:ViewRowColumnHeaders?x=' + Math.round(pos.x) + '&y=' + Math.round(pos.y) +
+ '&width=' + Math.round(size.x) + '&height=' + Math.round(size.y);
+
this._map._socket.sendMessage(payload);
},
// sends the .uno:SheetGeometryData command optionally with arguments.
- requestSheetGeomtryData: function (flags) {
+ requestSheetGeometryData: function (flags) {
var unoCmd = '.uno:SheetGeometryData';
- var haveArgs = (typeof flags == 'object' && (flags.columns === true || flags.rows === true));
+ var haveArgs = (typeof flags == 'object' &&
+ (flags.columns === true || flags.rows === true) &&
+ (flags.columns !== flags.rows));
var payload = 'commandvalues command=' + unoCmd;
if (haveArgs) {
@@ -533,9 +572,15 @@ L.CalcTileLayer = L.TileLayer.extend({
this._map._socket.sendMessage(payload);
},
- _handleViewRowColumnHeadersMsg: function (jsonMsgObj) {
+ // Sends a notification to the row/col header and gridline controls that
+ // they need repainting.
+ // viewAreaData is the parsed .uno:ViewRowColumnHeaders JSON if that source is used.
+ // else it should be undefined.
+ _updateHeadersGridLines: function (viewAreaData, updateCols, updateRows) {
this._map.fire('viewrowcolumnheaders', {
- data: jsonMsgObj,
+ data: viewAreaData,
+ updaterows: updateRows,
+ updatecolumns: updateCols,
cursor: this._getCursorPosSize(),
selection: this._getSelectionHeaderData(),
converter: this._twipsToPixels,
@@ -544,8 +589,17 @@ L.CalcTileLayer = L.TileLayer.extend({
},
_handleSheetGeometryDataMsg: function (jsonMsgObj) {
- // TODO: use the L.SheetGeometry datastructure
- this._map.sheetGeomData = jsonMsgObj;
+ if (!this.sheetGeometry) {
+ this.sheetGeometry = new L.SheetGeometry(jsonMsgObj,
+ this._tileWidthTwips, this._tileHeightTwips,
+ this._tileSize, this._tilePixelScale);
+ }
+
+ this.sheetGeometry.update(jsonMsgObj);
+ this.sheetGeometry.setViewArea(this._pixelsToTwips(this._map._getTopLeftPoint()),
+ this._pixelsToTwips(this._map.getSize()));
+ this._updateHeadersGridLines(undefined, true /* updateCols */,
+ true /* updateRows */);
},
_onCommandValuesMsg: function (textMsg) {
@@ -560,7 +614,7 @@ L.CalcTileLayer = L.TileLayer.extend({
var comment;
if (values.commandName === '.uno:ViewRowColumnHeaders') {
- this._handleViewRowColumnHeadersMsg(values);
+ this._updateHeadersGridLines(values);
} else if (values.commandName === '.uno:SheetGeometryData') {
this._handleSheetGeometryDataMsg(values);
@@ -697,6 +751,14 @@ L.SheetGeometry = L.Class.extend({
return true;
},
+ getColumnsGeometry: function () {
+ return this._columns;
+ },
+
+ getRowsGeometry: function () {
+ return this._rows;
+ },
+
// returns an object with keys 'start' and 'end' indicating the
// column range in the current view area.
getViewColumnRange: function () {
diff --git a/loleaflet/src/map/Map.js b/loleaflet/src/map/Map.js
index dbc376765..0cd8f9282 100644
--- a/loleaflet/src/map/Map.js
+++ b/loleaflet/src/map/Map.js
@@ -324,7 +324,7 @@ L.Map = L.Evented.extend({
this._socket.sendMessage('commandvalues command=.uno:LanguageStatus');
this._socket.sendMessage('commandvalues command=.uno:ViewAnnotations');
if (this._docLayer._docType === 'spreadsheet') {
- this._docLayer.requestViewRowColumnData();
+ this._docLayer.refreshViewData();
}
this._docLayer._getToolbarCommandsValues();
},
More information about the Libreoffice-commits
mailing list