@sapui5/sap.ui.vbm 1.141.0 → 1.143.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sapui5/sap.ui.vbm",
3
- "version": "1.141.0",
3
+ "version": "1.143.0",
4
4
  "description": "SAPUI5 Library sap.ui.vbm",
5
5
  "homepage": "https://sap.github.io/ui5-tooling/pages/SAPUI5/",
6
6
  "author": "SAP SE (https://www.sap.com)",
@@ -3,7 +3,7 @@
3
3
  <name>sap.ui.vbm</name>
4
4
  <vendor>SAP SE</vendor>
5
5
  <copyright>SAP UI development toolkit for HTML5 (SAPUI5) (c) Copyright 2009-2012 SAP AG. All rights reserved</copyright>
6
- <version>1.141.0</version>
6
+ <version>1.143.0</version>
7
7
 
8
8
  <documentation>SAP UI library: sap.ui.vbm</documentation>
9
9
 
@@ -24,7 +24,7 @@ sap.ui.define([
24
24
  * @param {string} [sId] id for the new control, generated automatically if no id is given
25
25
  * @param {object} [mSettings] initial settings for the new object
26
26
  * @author SAP SE
27
- * @version 1.141.0
27
+ * @version 1.143.0
28
28
  * @extends sap.ui.core.Element
29
29
  * @constructor
30
30
  * @public
@@ -47,7 +47,7 @@ sap.ui.define([
47
47
  * @param {string} [sId] id for the new control, generated automatically if no id is given
48
48
  * @param {object} [mSettings] initial settings for the new object
49
49
  * @author SAP SE
50
- * @version 1.141.0
50
+ * @version 1.143.0
51
51
  * @extends sap.ui.core.Element
52
52
  * @constructor
53
53
  * @public
@@ -238,7 +238,7 @@ sap.ui.define([
238
238
 
239
239
  this._colladaBounds = null;
240
240
 
241
-
241
+
242
242
  // this._lassoTracker = null;
243
243
  };
244
244
 
@@ -330,7 +330,7 @@ sap.ui.define([
330
330
  this._rectangleTracker = new RectangleTracker(this);
331
331
  // // this._lassoTracker = new LassoTracker(this);
332
332
  // if(rectangleSelect)
333
-
333
+
334
334
  // if(lassoSelect && !rectangleSelect)
335
335
  // {
336
336
  // this._lassoSelect = "created";
@@ -348,7 +348,7 @@ sap.ui.define([
348
348
  this._dragDropHandler.destroy();
349
349
  this._dragDropHandler = null;
350
350
  this._colladaBounds = null;
351
- this._rectangleTracker = null;
351
+ this._rectangleTracker = null;
352
352
  // this._lassoTracker = null;
353
353
  this._viewport.removeEventDelegate(viewportEventDelegate);
354
354
  // onBeforeRendering unsubscribes from DOM events.
@@ -421,51 +421,51 @@ sap.ui.define([
421
421
  that._viewport.setBusy(true);
422
422
 
423
423
  that._update = that._update
424
- .then(function() {
425
- that._parser.loadVBIJSON(payload);
426
-
427
- return that._sceneBuilder.synchronize();
428
- })
429
- .then(function() {
430
- // further processing after scene(s) has been updated
431
- that._processAutomation(payload);
432
- that._processDetailWindow();
433
- // that._createCollada(payload);
434
- // check if last hover instance is still exist (it may be erased during update)
435
- that._context.voQueues.toRemove.forEach(function(instances) {
436
- instances.forEach(function(instance) {
437
- if (that._hoverInstance === instance) {
438
- that._hoverInstance = null;
439
- }
424
+ .then(function() {
425
+ that._parser.loadVBIJSON(payload);
426
+
427
+ return that._sceneBuilder.synchronize();
428
+ })
429
+ .then(function() {
430
+ // further processing after scene(s) has been updated
431
+ that._processAutomation(payload);
432
+ that._processDetailWindow();
433
+ // that._createCollada(payload);
434
+ // check if last hover instance is still exist (it may be erased during update)
435
+ that._context.voQueues.toRemove.forEach(function(instances) {
436
+ instances.forEach(function(instance) {
437
+ if (that._hoverInstance === instance) {
438
+ that._hoverInstance = null;
439
+ }
440
+ }, that);
440
441
  }, that);
441
- }, that);
442
442
 
443
443
 
444
- if (that._colladaBounds) {
445
- that._colladaBounds.initialize();
446
- }
444
+ if (that._colladaBounds) {
445
+ that._colladaBounds.initialize();
446
+ }
447
447
 
448
- // update drag and drop handler
449
- if (that._dragDropHandler) {
450
- that._dragDropHandler.update();
451
- }
452
-
453
- // scene has changed -> adjust camera clipping planes
454
- that._viewport._resetBBox();
455
- that._viewport._updateCamera();
448
+ // update drag and drop handler
449
+ if (that._dragDropHandler) {
450
+ that._dragDropHandler.update();
451
+ }
456
452
 
457
- // clear before next update
458
- that._context.voQueues.clear();
459
- that._context.sceneQueues.clear();
460
- that._context.windowQueues.clear();
453
+ // scene has changed -> adjust camera clipping planes
454
+ that._viewport._resetBBox();
455
+ that._viewport._updateCamera();
461
456
 
462
- that._viewport.setBusy(false);
463
- });
457
+ // clear before next update
458
+ that._context.voQueues.clear();
459
+ that._context.sceneQueues.clear();
460
+ that._context.windowQueues.clear();
461
+
462
+ that._viewport.setBusy(false);
463
+ });
464
464
  // return last promise in chain
465
-
465
+
466
466
  return that._update;
467
467
  };
468
-
468
+
469
469
  Adapter3D.prototype._processDetailWindow = function(payload) {
470
470
  // show first only detail window from toAdd queue
471
471
  // ignore all other detail windows as we can show only one at a time in compare to ActiveX implementation
@@ -791,12 +791,12 @@ sap.ui.define([
791
791
  };
792
792
 
793
793
  Adapter3D.prototype._genericEventHandler = function(name, event) {
794
-
794
+
795
795
  var homeButtonKey = Utilities.parseKeyboardShortcut(this._context.config.has("HOME_VIEW") ? this._context.config.get("HOME_VIEW") : "72");
796
-
796
+
797
797
  if (Utilities.matchKeyboardShortcut(event, homeButtonKey)) {
798
798
  this._viewport.applyCameraHome(false); // no fly-to animation needed here
799
- return;
799
+ return;
800
800
  }
801
801
 
802
802
  var instance = event.instance;
@@ -1167,9 +1167,9 @@ sap.ui.define([
1167
1167
  this._skipClick = false;
1168
1168
  this._handleHover(event);
1169
1169
  } else if (this._clickTimerId) {
1170
- clearTimeout(this._clickTimerId);
1171
- this._clickTimerId = null;
1172
- this._handleDoubleClick(event);
1170
+ clearTimeout(this._clickTimerId);
1171
+ this._clickTimerId = null;
1172
+ this._handleDoubleClick(event);
1173
1173
  } else {
1174
1174
  this._clickTimerId = setTimeout(function() {
1175
1175
  this._clickTimerId = null;
@@ -1193,6 +1193,14 @@ sap.ui.define([
1193
1193
  * @private
1194
1194
  */
1195
1195
  Adapter3D.prototype._extendEventWithSelection = function(event) {
1196
+
1197
+ // As we want to manintain the state of object(selected/not selected)
1198
+ // In case of drag and drop we will not calling further function
1199
+ if (this._dragDropHandler.isDragAndDrop) {
1200
+ this._dragDropHandler.isDragAndDrop = false;
1201
+ return;
1202
+ }
1203
+
1196
1204
  var instance = event.instance;
1197
1205
  if (instance) {
1198
1206
  if (event.originalEvent.type === "click") {
@@ -1210,10 +1218,19 @@ sap.ui.define([
1210
1218
  action = "select";
1211
1219
  exclusive = true;
1212
1220
  }
1213
- event.selectionChanges = this._changeSelection(instance, action, exclusive);
1221
+ if (instance.object3D) {
1222
+ event.selectionChanges = this._changeSelectionAddtvAndSubtv(instance, action, exclusive);
1223
+ } else {
1224
+ event.selectionChanges = this._changeSelection(instance, action, exclusive);
1225
+ }
1226
+
1214
1227
  }
1215
1228
  } else {
1216
- event.selectionChanges = this._changeSelection(instance, "toggle", false);
1229
+ if (instance.object3D) {
1230
+ event.selectionChanges = this._changeSelectionAddtvAndSubtv(instance, "toggle", false);
1231
+ } else {
1232
+ event.selectionChanges = this._changeSelection(instance, "toggle", false);
1233
+ }
1217
1234
  }
1218
1235
  }
1219
1236
  };
@@ -1252,7 +1269,7 @@ sap.ui.define([
1252
1269
  deselected = group.selected.splice(0);
1253
1270
  }
1254
1271
  group.selected.push(instance);
1255
- selected = [ instance ];
1272
+ selected = [instance];
1256
1273
  }
1257
1274
  }
1258
1275
  } else if (action === "toggle") {
@@ -1269,15 +1286,15 @@ sap.ui.define([
1269
1286
  }
1270
1287
  // Select instance
1271
1288
  group.selected.push(instance);
1272
- selected = [ instance ];
1289
+ selected = [instance];
1273
1290
  }
1274
1291
  }
1275
1292
 
1276
- selected.forEach(function(instance) {
1293
+ selected.forEach(function (instance) {
1277
1294
  instance["VB:s"] = "true";
1278
1295
  });
1279
1296
 
1280
- deselected.forEach(function(instance) {
1297
+ deselected.forEach(function (instance) {
1281
1298
  instance["VB:s"] = "false";
1282
1299
  });
1283
1300
 
@@ -1285,7 +1302,132 @@ sap.ui.define([
1285
1302
  selected: selected,
1286
1303
  deselected: deselected
1287
1304
  }
1288
- };
1305
+ };
1306
+
1307
+ Adapter3D.prototype._changeSelectionAddtvAndSubtv = function (instance, action, exclusive) {
1308
+ var selected = [];
1309
+ var deselected = [];
1310
+ var group = instance.voGroup;
1311
+ var wasSelected = toBoolean(instance["VB:s"]);
1312
+ var selectedIndex;
1313
+
1314
+ if (action === "select") {
1315
+ if (group.maxSel !== "0") {
1316
+ if (wasSelected) {
1317
+ if (exclusive) {
1318
+ // Deselect other selected instances in the group.
1319
+ selectedIndex = group.selected.indexOf(instance);
1320
+
1321
+ // it was manually selected
1322
+ if (selectedIndex >= 0) {
1323
+ deselected = group.selected.splice(selectedIndex + 1).concat(group.selected.splice(0, selectedIndex));
1324
+
1325
+ // deselect all elements from rect selection as well
1326
+ let found = [...this._rectangleTracker._selected];
1327
+ for (let i = 0; i < found.length; i++) {
1328
+ if (instance != found[i]._sapInstance) {
1329
+ deselected.push(found[i]._sapInstance);
1330
+ }
1331
+ }
1332
+
1333
+ // To remove any dups present
1334
+ deselected = [...new Map(deselected.map(item => [item.id, item])).values()];
1335
+
1336
+ this._rectangleTracker._selected.clear();
1337
+ } else {
1338
+ // considering it is from rect selection.
1339
+ let matchingInstance = [...this._rectangleTracker._selected].find(u => u.uuid === instance.object3D.uuid);
1340
+
1341
+ deselected = group.selected.splice(0);
1342
+
1343
+ // deselect all elements from rect selection as well
1344
+ let found = [...this._rectangleTracker._selected];
1345
+ for (let i = 0; i < found.length; i++) {
1346
+
1347
+ if (matchingInstance.uuid != found[i].uuid) {
1348
+ deselected.push(found[i]._sapInstance);
1349
+ this._rectangleTracker._selected.delete(found[i]);
1350
+ }
1351
+ }
1352
+
1353
+ // To remove any dups present
1354
+ deselected = [...new Map(deselected.map(item => [item.id, item])).values()];
1355
+
1356
+ }
1357
+
1358
+ }
1359
+ } else {
1360
+ if (exclusive || group.maxSel === "1") {
1361
+
1362
+ // Deselect other selected instances in the group.
1363
+ selectedIndex = group.selected.indexOf(instance);
1364
+
1365
+ if (selectedIndex >= 0) {
1366
+ deselected = group.selected.splice(selectedIndex + 1).concat(group.selected.splice(0, selectedIndex));
1367
+ } else {
1368
+ deselected = group.selected.splice(0);
1369
+ }
1370
+
1371
+ let found = [...this._rectangleTracker._selected];
1372
+ for (let i = 0; i < found.length; i++) {
1373
+ deselected.push(found[i]._sapInstance);
1374
+ }
1375
+
1376
+ // To remove any dups present
1377
+ deselected = [...new Map(deselected.map(item => [item.id, item])).values()];
1378
+
1379
+ this._rectangleTracker._selected.clear();
1380
+ }
1381
+ if (!selectedIndex || selectedIndex < 0) {
1382
+ group.selected.push(instance);
1383
+ }
1384
+ selected = [instance];
1385
+ }
1386
+ }
1387
+ } else if (action === "toggle") {
1388
+ if (wasSelected) {
1389
+ if (group.minSel === "0" || group.selected.length > 1) {
1390
+ // Deselect instance
1391
+ selectedIndex = group.selected.indexOf(instance);
1392
+ let found = [...this._rectangleTracker._selected].find(u => u.uuid === instance.object3D.uuid);
1393
+
1394
+ if (found) {
1395
+ this._rectangleTracker._selected.delete(found);
1396
+ }
1397
+
1398
+ // if the instance id previously selected and we are still not able to get it in data
1399
+ // we can still go ahead and that instance in deselected array to deselect it.
1400
+ if (selectedIndex < 0) {
1401
+ deselected.push(instance);
1402
+ } else {
1403
+ deselected = group.selected.splice(selectedIndex, 1);
1404
+ }
1405
+
1406
+ }
1407
+ } else if (group.maxSel !== "0") {
1408
+ if (group.maxSel === "1") {
1409
+ // Deselect all
1410
+ deselected = group.selected.splice(0);
1411
+ }
1412
+ // Select instance
1413
+ group.selected.push(instance);
1414
+ selected = [instance];
1415
+ }
1416
+ }
1417
+
1418
+ selected.forEach(function (instance) {
1419
+ instance["VB:s"] = "true";
1420
+ });
1421
+
1422
+ deselected.forEach(function (instance) {
1423
+ instance["VB:s"] = "false";
1424
+ });
1425
+
1426
+ return {
1427
+ selected: selected,
1428
+ deselected: deselected
1429
+ }
1430
+ };
1289
1431
 
1290
1432
 
1291
1433
  Adapter3D.prototype.enableRectangularSelection = function() {
@@ -23,7 +23,7 @@ sap.ui.define([
23
23
  *
24
24
  * @public
25
25
  * @author SAP SE
26
- * @version 1.141.0
26
+ * @version 1.143.0
27
27
  * @extends sap.ui.core.Control
28
28
  * @alias sap.ui.vbm.Viewport
29
29
  */
@@ -22,7 +22,7 @@ sap.ui.define([
22
22
  *
23
23
  * @private
24
24
  * @author SAP SE
25
- * @version 1.141.0
25
+ * @version 1.143.0
26
26
  * @alias sap.ui.vbm.adapter3d.ColladaBounds
27
27
  */
28
28
  var ColladaBounds = BaseObject.extend("sap.ui.vbm.adapter3d.ColladaBounds", /** @lends sap.ui.vbm.adapter3d.ColladaBounds.prototype */ {
@@ -83,7 +83,7 @@ sap.ui.define([
83
83
  *
84
84
  * @private
85
85
  * @author SAP SE
86
- * @version 1.141.0
86
+ * @version 1.143.0
87
87
  * @alias sap.ui.vbm.adapter3d.DragDropHandler
88
88
  */
89
89
  var DragDropHandler = BaseObject.extend("sap.ui.vbm.adapter3d.DragDropHandler", /** @lends sap.ui.vbm.adapter3d.DragDropHandler.prototype */ {
@@ -99,6 +99,9 @@ sap.ui.define([
99
99
  this._camera = this._viewport._camera;
100
100
  this._cameraControls = this._viewport._cameraController;
101
101
 
102
+ // to detect the dragAndDrop happened
103
+ this.isDragAndDrop = false;
104
+
102
105
  // current action state
103
106
  this._state = STATE.PICK;
104
107
 
@@ -612,6 +615,9 @@ sap.ui.define([
612
615
  var payload = {
613
616
  version : "2.0",
614
617
  "xmlns:VB" : "VB",
618
+ Action : {
619
+ name : "DRAG_DROP"
620
+ },
615
621
  Data: {
616
622
  Merge: {
617
623
  N: []
@@ -638,7 +644,16 @@ sap.ui.define([
638
644
  var posAlias = this._adapter._parser.getAttributeAlias(dataType, posAttr);
639
645
  var keyAlias = this._adapter._parser.getAttributeAlias(dataType, instance.voGroup.keyAttributeName);
640
646
  var pos = instance.object3D.position;
641
- var value = pos.x.toFixed(5) + ";" + pos.y.toFixed(5) + ";" + pos.z.toFixed(5);
647
+ var value = pos.x.toFixed(5) + ";" + pos.y.toFixed(5) + ";" + pos.z.toFixed(5); // new pos
648
+
649
+ var strInitialPos = instance.pos.split(";"); // prev pos
650
+ var vectorInitialPos = new Vector3(parseFloat(strInitialPos[0]), parseFloat(strInitialPos[1]), parseFloat(strInitialPos[2]));
651
+
652
+ if (vectorInitialPos.distanceTo(pos) > 0.5) { // fault tolerence
653
+ this.isDragAndDrop = true;
654
+ } else {
655
+ this.isDragAndDrop = false;
656
+ }
642
657
 
643
658
  // make sure position is updated in all 3 places:
644
659
  // evaluated instance
@@ -29,7 +29,7 @@ sap.ui.define([
29
29
  *
30
30
  * @private
31
31
  * @author SAP SE
32
- * @version 1.141.0
32
+ * @version 1.143.0
33
33
  * @alias sap.ui.vbm.adapter3d.ModelHandler
34
34
  */
35
35
  var ModelHandler = BaseObject.extend("sap.ui.vbm.adapter3d.ModelHandler", /** @lends sap.ui.vbm.adapter3d.ModelHandler.prototype */ {
@@ -377,7 +377,7 @@ sap.ui.define([
377
377
  *
378
378
  * @private
379
379
  * @author SAP SE
380
- * @version 1.141.0
380
+ * @version 1.143.0
381
381
  * @alias sap.ui.vbm.adapter3d.ObjectFactory
382
382
  */
383
383
  var ObjectFactory = BaseObject.extend("sap.ui.vbm.adapter3d.ObjectFactory", /** @lends sap.ui.vbm.adapter3d.ObjectFactory.prototype */ {});
@@ -32,7 +32,7 @@ sap.ui.define([
32
32
  *
33
33
  * @private
34
34
  * @author SAP SE
35
- * @version 1.141.0
35
+ * @version 1.143.0
36
36
  * @alias sap.ui.vbm.adapter3d.PolygonHandler
37
37
  */
38
38
  var PolygonHandler = BaseObject.extend("sap.ui.vbm.adapter3d.PolygonHandler", /** @lends sap.ui.vbm.adapter3d.PolygonHandler.prototype */ {
@@ -39,7 +39,7 @@ sap.ui.define([
39
39
  *
40
40
  * @private
41
41
  * @author SAP SE
42
- * @version 1.141.0
42
+ * @version 1.143.0
43
43
  * @alias sap.ui.vbm.adapter3d.RectangleTracker
44
44
  */
45
45
  var RectangleTracker = BaseObject.extend("sap.ui.vbm.adapter3d.RectangleTracker", /** @lends sap.ui.vbm.adapter3d.RectangleTracker.prototype */ {
@@ -53,11 +53,15 @@ sap.ui.define([
53
53
  this._camera = this._viewport._camera;
54
54
  this._cameraControls = this._viewport._cameraController;
55
55
  this._selected = new Set();
56
+ this._previousSelected = new Set();
57
+ this.disableRect = false;
56
58
  this._renderer = this._renderer;
57
59
  this.init();
58
- var helper = new THREE.CameraHelper(this._camera);
59
- helper.geometry.setDrawRange(0, 0);
60
- this._addToScene(helper, this._scene, true, 1);
60
+ if (!this._adapter._cameraHelper) {
61
+ this._adapter._cameraHelper = new THREE.CameraHelper(this._camera);
62
+ this._adapter._cameraHelper.geometry.setDrawRange(0, 0);
63
+ this._addToScene(this._adapter._cameraHelper, this._scene, true, 1);
64
+ }
61
65
  this._snapBox = new THREE.BoxHelper(undefined, 0x00ffff);
62
66
  // invisible, layer #1 (disable hit test)
63
67
  this._addToScene(this._snapBox, this._scene, false, 1);
@@ -152,81 +156,22 @@ sap.ui.define([
152
156
  return; // Don't start selection if it's not the left button
153
157
  }
154
158
  this._updateController(true);
155
- this.onSelectStart(event);
156
- var that = this;
159
+ // To start the selection if our arrow is on white space or
160
+ // not particulary on selectable object.
161
+ if (window.getComputedStyle(event.target).cursor == "auto") {
162
+ this._cameraControls.setEnabled(false);
163
+ this.onSelectStart(event);
164
+ this.disableRect = true;
165
+ } else {
166
+ this.disableRect = false;
167
+ return;
168
+ }
157
169
  event.cursor = event.cursor || this._getXY(event);
158
170
  this._mouseDown = true;
159
171
  var rect = this._viewport.getDomRef().getBoundingClientRect();
160
172
  startPoint.x = (event.cursor.x / rect.width) * 2 - 1;
161
173
  startPoint.y = -(event.cursor.y / rect.height) * 2 + 1;
162
- var dataMap = new Map();
163
- var dataType;
164
- var keyAlias;
165
- if (!event.ctrlKey) {
166
- this._selected.forEach(function (item) {
167
- if (item.type != 'InstancedMesh' || item.type != 'PlaneGeometry') {
168
- var obj = {};
169
- if (item._sapInstance != undefined) {
170
- var val = item._sapInstance;
171
- item._sapInstance["VB:s"] = "false";
172
- that._adapter._sceneBuilder.updateHotInstance(val);
173
- dataType = item._sapInstance.voGroup.datasource; // VO group data source linked to a DataType by name
174
- keyAlias = that._adapter._parser.getAttributeAlias(dataType, item._sapInstance.voGroup.keyAttributeName);
175
- obj[keyAlias] = item._sapInstance.id;
176
- obj["VB:s"] = "false";
177
- } else if (item.userData.name == "ColladaBounds") {
178
- if (item.userData._sapInstance["VB:s"] == "true") {
179
- var instance = item.userData._sapInstance;
180
- var selectionChanges = that._adapter._changeSelection(instance, "toggle", false);
181
- that._adapter._sceneBuilder.updateSelection(selectionChanges.selected, selectionChanges.deselected);
182
- dataType = item.userData._sapInstance.voGroup.datasource; // VO group data source linked to a DataType by name
183
- keyAlias = that._adapter._parser.getAttributeAlias(dataType, item.userData._sapInstance.voGroup.keyAttributeName);
184
- obj[keyAlias] = item.userData.id;
185
- obj["VB:s"] = "false";
186
- }
187
- }
188
-
189
- var existingData = dataMap.get(dataType);
190
- if (existingData != undefined ) {
191
- // Check if there's already an entry for this dataType
192
- var existingEntry = existingData.find(function (entry) {
193
- return entry.name === dataType;
194
- });
195
-
196
- if (existingEntry) {
197
- // If an entry exists for this dataType, push the new object to its E array if it's not already present
198
- var existingObject = existingEntry.E.find(function (e) {
199
- if (item._sapInstance != undefined)
200
- return e[keyAlias] === item._sapInstance.id
201
- else
202
- return e[keyAlias] === item.userData.id;
203
- });
204
- if (!existingObject && JSON.stringify(obj) !== '{}' ) {
205
- // If the object doesn't exist, push it to the E array
206
- existingEntry.E.push(obj);
207
- }
208
- }
209
- } else {
210
- // If no data exists for this dataType, create a new array and add the object
211
- dataMap.set(dataType, [{
212
- name: dataType,
213
- E: [obj]
214
- }]);
215
- }
216
- }
217
- });
218
-
219
- if (dataMap != undefined) {
220
- var payload = that._constructPayload(dataMap);
221
- if (payload.Data.Merge.N.length > 0) {
222
- this._adapter.fireSubmit({
223
- data: JSON.stringify(payload)
224
- });
225
- }
226
- }
227
- }
228
-
229
- this._selected.clear();
174
+ this._previousSelected = new Set(this._selected);
230
175
  };
231
176
 
232
177
  RectangleTracker.prototype._onPointerMove = function (event) {
@@ -242,106 +187,168 @@ sap.ui.define([
242
187
  // this._cameraControls.enableRotate = false;
243
188
  // }
244
189
  }
245
- RectangleTracker.prototype._onPointerUp = function (event) {
246
- this._updateController(true);
247
- if (!this._mouseDown) {
248
- var that = this;
249
- event.cursor = event.cursor || this._getXY(event);
250
- var rect = this._viewport.getDomRef().getBoundingClientRect();
251
- endPoint.x = (event.cursor.x / rect.width) * 2 - 1;
252
- endPoint.y = -(event.cursor.y / rect.height) * 2 + 1;
253
- endPoint.z = 0.5
254
- var isSelected = this.selecting(_frustum);
255
- var dataMap = new Map();
256
- var dataType;
257
- var keyAlias;
258
- var obj = {};
259
- if (isSelected.length > 0) {
260
- for (var i = 0; i < isSelected.length; i++) {
261
- this._selected.add(isSelected[i]);
190
+ RectangleTracker.prototype.buildEntry = function (item, selected, items) {
191
+ let dataType, keyAlias;
192
+ let obj = {};
193
+
194
+ if (item._sapInstance != undefined) {
195
+ const val = item._sapInstance;
196
+ item._sapInstance["VB:s"] = selected ? "true" : "false";
197
+ // maybe updateHotInstance only for selected?
198
+ this._adapter._sceneBuilder.updateHotInstance(val);
199
+ dataType = item._sapInstance.voGroup.datasource;
200
+ keyAlias = this._adapter._parser.getAttributeAlias(dataType, item._sapInstance.voGroup.keyAttributeName);
201
+ obj[keyAlias] = item._sapInstance.id;
202
+ obj["VB:s"] = selected ? "true" : "false";
203
+ } else if (item.userData.name === "ColladaBounds") {
204
+ if (selected === true) {
205
+ var id = item.userData.id;
206
+ var meshCount = item.userData.count;
207
+ var count = 0;
208
+ items.forEach(function (itemA) {
209
+ if (itemA.userData.id == id)
210
+ count++;
211
+ });
212
+ if (count == meshCount) {
213
+ var instance = item.userData._sapInstance;
214
+ var selectionChanges = this._adapter._changeSelection(instance, "select", false);
215
+ this._adapter._sceneBuilder.updateSelection(selectionChanges.selected, selectionChanges.deselected);
216
+ dataType = item.userData._sapInstance.voGroup.datasource; // VO group data source linked to a DataType by name
217
+ keyAlias = this._adapter._parser.getAttributeAlias(dataType, item.userData._sapInstance.voGroup.keyAttributeName);
218
+ obj[keyAlias] = item.userData.id;
219
+ obj["VB:s"] = "true";
220
+ }
221
+ } else {
222
+ if (item.userData._sapInstance["VB:s"] == "true") {
223
+ var instance = item.userData._sapInstance;
224
+ var selectionChanges = this._adapter._changeSelection(instance, "toggle", false);
225
+ this._adapter._sceneBuilder.updateSelection(selectionChanges.selected, selectionChanges.deselected);
226
+ // your ColladaBounds logic with selected/deselected
227
+ dataType = item.userData._sapInstance.voGroup.datasource;
228
+ keyAlias = this._adapter._parser.getAttributeAlias(dataType, item.userData._sapInstance.voGroup.keyAttributeName);
229
+ obj[keyAlias] = item.userData.id;
230
+ obj["VB:s"] = selected ? "true" : "false";
262
231
  }
263
232
  }
264
- this._selected.forEach(function (item) {
265
- obj = {};
266
- if (item.type != 'InstancedMesh' || item.type != 'PlaneGeometry') {
267
- if (item._sapInstance != undefined) {
268
- var val = item._sapInstance;
269
- item._sapInstance["VB:s"] = "true";
270
- that._adapter._sceneBuilder.updateHotInstance(val);
271
- dataType = item._sapInstance.voGroup.datasource; // VO group data source linked to a DataType by name
272
- keyAlias = that._adapter._parser.getAttributeAlias(dataType, item._sapInstance.voGroup.keyAttributeName);
273
- obj[keyAlias] = item._sapInstance.id;
274
- obj["VB:s"] = "true";
275
- // that._adapter._handleHover(val);
276
- } else if (item.userData.name == "ColladaBounds") {
277
- var id = item.userData.id;
278
- var meshCount = item.userData.count;
279
- var count = 0;
280
- that._selected.forEach(function (itemA) {
281
- if (itemA.userData.id == id)
282
- count++;
283
- });
284
- if (count == meshCount) {
285
- var instance = item.userData._sapInstance;
286
- var selectionChanges = that._adapter._changeSelection(instance, "select", false);
287
- that._adapter._sceneBuilder.updateSelection(selectionChanges.selected, selectionChanges.deselected);
288
- dataType = item.userData._sapInstance.voGroup.datasource; // VO group data source linked to a DataType by name
289
- keyAlias = that._adapter._parser.getAttributeAlias(dataType, item.userData._sapInstance.voGroup.keyAttributeName);
290
- obj[keyAlias] = item.userData.id;
291
- obj["VB:s"] = "true";
292
- }
293
- }
233
+ }
294
234
 
235
+ return { dataType, keyAlias, obj };
236
+ };
295
237
 
296
- var existingData = dataMap.get(dataType);
297
- if (existingData != undefined) {
298
- // Check if there's already an entry for this dataType
299
- var existingEntry = existingData.find(function (entry) {
300
- return entry.name === dataType;
301
- });
302
- if (existingEntry) {
303
- // If an entry exists for this dataType, push the new object to its E array if it's not already present
304
- var existingObject = existingEntry.E.find(function (e) {
305
- if (item._sapInstance != undefined)
306
- return e[keyAlias] === item._sapInstance.id
307
- else
308
- return e[keyAlias] === item.userData.id;
309
- });
310
- if (!existingObject && JSON.stringify(obj) !== '{}') {
311
- // If the object doesn't exist, push it to the E array
312
- existingEntry.E.push(obj);
313
- }
314
- }
315
- } else {
316
- // If no data exists for this dataType, create a new array and add the object
317
- dataMap.set(dataType, [{
318
- name: dataType,
319
- E: [obj]
320
- }]);
238
+ RectangleTracker.prototype.addToDataMap = function (dataMap, dataType, obj, keyAlias, item) {
239
+ if (!dataType || !obj) return;
240
+ const existingData = dataMap.get(dataType);
241
+ if (existingData) {
242
+ const existingEntry = existingData.find(entry => entry.name === dataType);
243
+ if (existingEntry) {
244
+ const existingObject = existingEntry.E.find(e => {
245
+ if (item._sapInstance != undefined)
246
+ return e[keyAlias] === item._sapInstance.id;
247
+ else
248
+ return e[keyAlias] === item.userData.id;
249
+ });
250
+ if (!existingObject && JSON.stringify(obj) !== '{}') existingEntry.E.push(obj);
251
+ }
252
+ } else {
253
+ dataMap.set(dataType, [{ name: dataType, E: [obj] }]);
254
+ }
255
+ };
256
+
257
+ RectangleTracker.prototype._onPointerUp = function (event) {
258
+ this._updateController(true);
259
+ if (this._mouseDown) return;
260
+
261
+ // case we are restricting rect selection to achieve drag drop, camera movement and additive single as well
262
+ if (!this.disableRect) return;
263
+
264
+ event.cursor = event.cursor || this._getXY(event);
265
+ var rect = this._viewport.getDomRef().getBoundingClientRect();
266
+ endPoint.x = (event.cursor.x / rect.width) * 2 - 1;
267
+ endPoint.y = -(event.cursor.y / rect.height) * 2 + 1;
268
+ endPoint.z = 0.5
269
+
270
+ const inside = this.selecting(_frustum); // all objects in rectangle
271
+ if (!inside || inside.length === 0) {
272
+ this._mouseDown = false;
273
+ this._cameraControls.setEnabled(true);
274
+ this._dom.style.cursor = this._hovered ? "pointer" : "auto";
275
+ this.onSelectOver();
276
+ return;
277
+ }
278
+ // build new selection set
279
+ const newSelected = new Set(inside);
280
+
281
+ // clearing all selected item
282
+ // do not worry as we are having selected item stored in _previousSelected set
283
+ // and newly selected are in newSelected set
284
+ this._selected.clear();
285
+
286
+ var deselected = [];
287
+
288
+ if (!event.ctrlKey && !event.shiftKey) {
289
+ // deselect items not in rectangle anymore
290
+ deselected = [...this._previousSelected].filter(i => !newSelected.has(i));
291
+ let instance = newSelected?.values()?.next()?.value?._sapInstance; // get 1st instance;
292
+
293
+ if (instance) {
294
+ var group = instance.voGroup;
295
+ const removeSelected = group.selected.reduceRight((acc, i, idx) => {
296
+ if (!newSelected.has(i.object3D)) {
297
+ acc.push(...group.selected.splice(idx, 1));
321
298
  }
322
-
323
- }
324
- });
299
+ return acc;
300
+ }, []);
301
+
302
+ deselected = [...deselected, ...removeSelected.map(item => ({ _sapInstance: item }))]; // to deselect manually selected objects.
303
+
304
+ }
325
305
 
306
+ } else {
307
+ // additive selection
308
+ // so maintain prevselected item as well.
309
+ [...this._previousSelected].forEach(i => this._selected.add(i));
326
310
  }
327
- if (dataMap != undefined) {
328
- var payload = that._constructPayload(dataMap);
311
+
312
+ // update your internal set
313
+ newSelected.forEach(i => this._selected.add(i));
314
+
315
+ // build a single dataMap for deselection + selection
316
+ const dataMap = new Map();
317
+
318
+ // handle deselection
319
+ deselected.forEach(item => {
320
+ const { dataType, keyAlias, obj } = this.buildEntry(item, false, deselected); // VB:s false
321
+ this.addToDataMap(dataMap, dataType, obj, keyAlias, item);
322
+ });
323
+
324
+ // handle selection
325
+ inside.forEach(item => {
326
+ const { dataType, keyAlias, obj } = this.buildEntry(item, true, inside); // VB:s true
327
+ this.addToDataMap(dataMap, dataType, obj, keyAlias, item);
328
+ });
329
+
330
+ if (dataMap.size > 0) {
331
+ const payload = this._constructPayload(dataMap);
329
332
  if (payload.Data.Merge.N.length > 0) {
330
- this._adapter.fireSubmit({
331
- data: JSON.stringify(payload)
332
- });
333
+ this._adapter.fireSubmit({ data: JSON.stringify(payload) });
333
334
  }
334
335
  }
336
+
335
337
  this._mouseDown = false;
336
338
  this._dom.style.cursor = this._hovered ? "pointer" : "auto";
339
+ this._cameraControls.setEnabled(true);
337
340
  this._updateController(true);
338
341
  this.onSelectOver();
339
342
  };
340
343
 
344
+
341
345
  RectangleTracker.prototype._constructPayload = function (dataMap) {
342
346
  var payload = {
343
347
  version: "2.0",
344
348
  "xmlns:VB": "VB",
349
+ Action : {
350
+ name : "RECTANGULAR_SELECTION"
351
+ },
345
352
  Data: {
346
353
  Merge: {
347
354
  N: []
@@ -464,39 +471,51 @@ sap.ui.define([
464
471
  var minY = Math.min(startPoint.y, endPoint.y);
465
472
  var maxY = Math.max(startPoint.y, endPoint.y);
466
473
 
474
+
475
+ _vecNear.setFromMatrixPosition(this._camera.matrixWorld);
467
476
  // Define corners in NDC (normalized device coordinates)
468
477
  _vecTopLeft.set(minX, maxY, 0);
469
478
  _vecTopRight.set(maxX, maxY, 0);
470
479
  _vecDownRight.set(maxX, minY, 0);
471
480
  _vecDownLeft.set(minX, minY, 0);
472
-
473
- // Camera position
474
- _vecNear.setFromMatrixPosition(this._camera.matrixWorld);
475
-
481
+
476
482
  _vecTopLeft.unproject(this._camera);
477
483
  _vecTopRight.unproject(this._camera);
478
484
  _vecDownRight.unproject(this._camera);
479
485
  _vecDownLeft.unproject(this._camera);
480
486
 
481
- // Far points (deep into the scene)
482
- _vectemp1.copy(_vecTopLeft).sub(_vecNear).normalize().multiplyScalar(this.deep).add(_vecNear);
483
- _vectemp2.copy(_vecTopRight).sub(_vecNear).normalize().multiplyScalar(this.deep).add(_vecNear);
484
- _vectemp3.copy(_vecDownRight).sub(_vecNear).normalize().multiplyScalar(this.deep).add(_vecNear);
485
- _vectemp4.copy(_vecDownLeft).sub(_vecNear).normalize().multiplyScalar(this.deep).add(_vecNear);
487
+ _vectemp1.copy(_vecTopLeft).sub(_vecNear);
488
+ _vectemp2.copy(_vecTopRight).sub(_vecNear);
489
+ _vectemp3.copy(_vecDownRight).sub(_vecNear);
490
+ _vectemp4.copy(_vecDownLeft).sub(_vecNear)
491
+
492
+ _vectemp1.normalize();
493
+ _vectemp2.normalize();
494
+ _vectemp3.normalize();
495
+ _vectemp4.normalize();
496
+
497
+
498
+ _vectemp1.multiplyScalar(this.deep);
499
+ _vectemp2.multiplyScalar(this.deep);
500
+ _vectemp3.multiplyScalar(this.deep);
501
+ _vectemp4.multiplyScalar(this.deep);
502
+ _vectemp1.sub(_vecNear);
503
+ _vectemp2.sub(_vecNear);
504
+ _vectemp3.sub(_vecNear);
505
+ _vectemp4.sub(_vecNear);
486
506
 
487
507
  var planes = _frustum.planes;
488
508
 
489
- // Build planes around the selection frustum
490
- planes[0].setFromCoplanarPoints(_vecNear, _vecTopLeft, _vecTopRight); // top
491
- planes[1].setFromCoplanarPoints(_vecNear, _vecTopRight, _vecDownRight); // right
492
- planes[2].setFromCoplanarPoints(_vecNear, _vecDownRight, _vecDownLeft); // bottom
493
- planes[3].setFromCoplanarPoints(_vecNear, _vecDownLeft, _vecTopLeft); // left
494
- planes[4].setFromCoplanarPoints(_vecTopRight, _vecDownRight, _vecDownLeft); // near plane
495
- planes[5].setFromCoplanarPoints(_vectemp3, _vectemp2, _vectemp1); // far plane
509
+ planes[0].setFromCoplanarPoints(_vecNear, _vecTopLeft, _vecTopRight);
510
+ planes[1].setFromCoplanarPoints(_vecNear, _vecTopRight, _vecDownRight);
511
+ planes[2].setFromCoplanarPoints(_vecDownRight, _vecDownLeft, _vecNear);
512
+ planes[3].setFromCoplanarPoints(_vecDownLeft, _vecTopLeft, _vecNear);
513
+ planes[4].setFromCoplanarPoints(_vecTopRight, _vecDownRight, _vecDownLeft);
514
+ planes[5].setFromCoplanarPoints(_vectemp3, _vectemp2, _vectemp1);
496
515
  planes[5].normal.multiplyScalar(-1);
497
516
  }
498
517
 
499
- return _frustum; // ✅ return the frustum so selecting() can use it
518
+
500
519
  };
501
520
 
502
521
  RectangleTracker.prototype.searchChildInFrustum = function (frustum, object) {
@@ -603,7 +622,7 @@ sap.ui.define([
603
622
  this._camera = null;
604
623
  this._cameraControls = null;
605
624
  this._raycaster = null;
606
- this._selected = null;
625
+ // this._selected = null;
607
626
  this._renderer = null;
608
627
  this._element = null;
609
628
  this._snapBox = null;
@@ -47,7 +47,7 @@ sap.ui.define([
47
47
  *
48
48
  * @private
49
49
  * @author SAP SE
50
- * @version 1.141.0
50
+ * @version 1.143.0
51
51
  * @alias sap.ui.vbm.adapter3d.SceneBuilder
52
52
  */
53
53
  var SceneBuilder = BaseObject.extend("sap.ui.vbm.adapter3d.SceneBuilder", /** @lends sap.ui.vbm.adapter3d.SceneBuilder.prototype */ {
@@ -56,7 +56,7 @@ sap.ui.define([
56
56
  *
57
57
  * @private
58
58
  * @author SAP SE
59
- * @version 1.141.0
59
+ * @version 1.143.0
60
60
  * @alias sap.ui.vbm.adapter3d.VBIJSONParser
61
61
  */
62
62
  var VBIJSONParser = BaseObject.extend("sap.ui.vbm.adapter3d.VBIJSONParser", /** @lends sap.ui.vbm.adapter3d.VBIJSONParser.prototype */ {
@@ -20,7 +20,7 @@ sap.ui.define([
20
20
  * @namespace
21
21
  * @alias sap.ui.vbm
22
22
  * @author SAP SE
23
- * @version 1.141.0
23
+ * @version 1.143.0
24
24
  * @public
25
25
  */
26
26
 
@@ -46,7 +46,7 @@ sap.ui.define([
46
46
  "sap.ui.vbm.ClusterBase", "sap.ui.vbm.ClusterTree", "sap.ui.vbm.ClusterGrid", "sap.ui.vbm.ClusterDistance", "sap.ui.vbm.Heatmap",
47
47
  "sap.ui.vbm.HeatPoint", "sap.ui.vbm.ClusterContainer", "sap.ui.vbm.Adapter", "sap.ui.vbm.Adapter3D"
48
48
  ],
49
- version: "1.141.0"
49
+ version: "1.143.0"
50
50
  });
51
51
 
52
52
  sap.ui.loader.config({
@@ -12,7 +12,7 @@ sap.ui.define([
12
12
  *
13
13
  * @private
14
14
  * @author SAP SE
15
- * @version 1.141.0
15
+ * @version 1.143.0
16
16
  * @alias sap.ui.vbm.vector.PayloadGenerator
17
17
  */
18
18
  var adapter = {};
@@ -12,7 +12,7 @@ sap.ui.define([
12
12
  *
13
13
  * @private
14
14
  * @author SAP SE
15
- * @version 1.141.0
15
+ * @version 1.143.0
16
16
  * @alias sap.ui.vbm.vector.RectangularSelection
17
17
  */
18
18
 
@@ -742,12 +742,27 @@ sap.ui.define([
742
742
  // code block
743
743
  }
744
744
  }
745
-
746
745
  }
747
746
  }
748
747
  }
749
748
 
750
-
749
+ featureCollection = Object.values(
750
+ featureCollection.reduce((acc, f) => {
751
+ const key = f.properties?.Key;
752
+ if (!key) return acc; // skip if no key
753
+
754
+ if (!acc[key]) {
755
+ acc[key] = { ...f };
756
+ } else {
757
+ // Merge properties if duplicate found
758
+ acc[key].properties = {
759
+ ...acc[key].properties,
760
+ ...f.properties
761
+ };
762
+ }
763
+ return acc;
764
+ }, {})
765
+ );
751
766
  if (obj.SAPVB.Data.Remove) {
752
767
 
753
768
  let del = obj.SAPVB.Data.Remove;
@@ -40,7 +40,6 @@ sap.ui.define([
40
40
  el.id = '__mapmarker' + spotid++;
41
41
  el.style.backgroundImage = `url(${base64decoded})`;
42
42
  el.style.backgroundSize = 'cover';
43
- el.style.pointerEvents = 'none';
44
43
  el.style.display = 'inline-block';
45
44
  el.style.transform = 'translate(-50%, -100%)';
46
45