bm-core-ui 2.8.3 → 2.9.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/build/@types/index.d.ts +321 -29
- package/build/BMCollectionView/BMCollectionView.js +29 -12
- package/build/BMCollectionView/BMCollectionViewFlowLayout.js +53 -11
- package/build/BMCollectionView/BMCollectionViewLayout.js +4 -1
- package/build/BMCoreUI.css +136 -12
- package/build/BMView/BMLayoutConstraint_v2.5.js +1 -1
- package/build/BMView/BMMenu.js +789 -64
- package/build/BMView/BMScrollView.js +1 -1
- package/build/BMView/BMTextFieldDelegate.js +6 -6
- package/build/BMViewLayoutEditor/BMLayoutEditorViewSettings.js +5 -2
- package/build/BMWindow/BMConfirmationPopup.js +21 -1
- package/build/BMWindow/BMPopover/BMPopover.js +310 -52
- package/build/BMWindow/BMWindow.js +57 -16
- package/lib/@types/BMCoreUI.min.d.ts +321 -29
- package/lib/BMCoreUI.min.js +1 -1
- package/package.json +1 -1
- package/CHANGELOG.md +0 -1771
- package/build/BMViewLayoutEditor/BMLayoutEditorDelegate.js +0 -59
- package/build/BMViewLayoutEditor/BMLayoutEditorSettingsDelegate.js +0 -46
- package/build/BMViewLayoutEditor/BMLayoutVariableProvider.js +0 -202
|
@@ -257,30 +257,38 @@ BMWindow.unregisterShowcaseElement = function (element) {
|
|
|
257
257
|
BMWindow.enterShowcase = async function () {
|
|
258
258
|
if (BMWindow._isShowcasing) return;
|
|
259
259
|
|
|
260
|
+
// Set a background color for the body to have a good contrast between the windows
|
|
261
|
+
// and the "empty space"
|
|
260
262
|
document.body.style.backgroundColor = 'rgb(60, 60, 60)';
|
|
261
263
|
|
|
262
264
|
BMWindow._isShowcasing = YES;
|
|
263
265
|
|
|
266
|
+
// Set up a handler to exit the showcase when clicking outside of any window
|
|
264
267
|
document.body.addEventListener('click', BMWindow.exitShowcase);
|
|
265
268
|
|
|
269
|
+
// Only include non-minimized windows in the showcase
|
|
266
270
|
let openWindows = BMWindow._windows.filter(value => !value._minimizedWindow);
|
|
267
271
|
|
|
268
|
-
|
|
269
|
-
|
|
272
|
+
// Add any window-like elements that have been registered to participate in the showcase
|
|
270
273
|
for (let element of BMWindow._showcaseElements) {
|
|
271
274
|
openWindows.unshift(element);
|
|
272
275
|
}
|
|
273
276
|
|
|
274
277
|
openWindows.forEach(window => {
|
|
278
|
+
// For each window, create a mask that consumes mouse events instead of the windows
|
|
279
|
+
// and disable pointer events for the windows
|
|
275
280
|
window.node.classList.add('BMWindowShowcaseWindow');
|
|
276
281
|
|
|
277
282
|
let selector = document.createElement('div');
|
|
278
283
|
selector.classList.add('BMWindowShowcaseWindowSelector');
|
|
279
284
|
selector.addEventListener('click', event => {
|
|
280
285
|
if (window.becomeKeyWindow) {
|
|
286
|
+
// If the clicked element is a window, make it the key window
|
|
281
287
|
window.becomeKeyWindow();
|
|
282
288
|
}
|
|
283
289
|
else {
|
|
290
|
+
// If a non-window element is clicked, bring it to the front by hiding
|
|
291
|
+
// all windows
|
|
284
292
|
BMWindow.hideAll();
|
|
285
293
|
}
|
|
286
294
|
BMWindow.exitShowcase();
|
|
@@ -289,16 +297,30 @@ BMWindow.enterShowcase = async function () {
|
|
|
289
297
|
window.node.appendChild(selector);
|
|
290
298
|
});
|
|
291
299
|
|
|
300
|
+
|
|
301
|
+
let viewportFrame = BMRectMake(0, 0, window.innerWidth, window.innerHeight);
|
|
302
|
+
// Create a copy of each window's frame which will be used to determine where to place each window
|
|
303
|
+
// in the showcase
|
|
292
304
|
let sourceRects = openWindows.map(window => window._fullScreen ? viewportFrame.copy() : window.frame.copy());
|
|
305
|
+
|
|
306
|
+
// Retain a copy of the original frames to determine what transforms to apply to each window
|
|
293
307
|
let originalRects = sourceRects.map(rect => rect.copy());
|
|
308
|
+
|
|
309
|
+
// Set to NO when no windows overlap
|
|
294
310
|
let overlap;
|
|
295
311
|
|
|
312
|
+
// Initialize the bounds with the viewport frame; this will expand to represent the entire area
|
|
313
|
+
// used by all windows as they get pushed apart
|
|
296
314
|
let bounds = viewportFrame.copy();
|
|
297
315
|
|
|
316
|
+
// Because the algorithm works through multiple iterations where each intersecting windows
|
|
317
|
+
// are pushed apart slightly, set a maximum number of iterations to avoid situations
|
|
318
|
+
// where a fully non-intersecting layout cannot be obtained in an acceptable amount of time
|
|
298
319
|
for (let i = 0; i < BM_WINDOW_SHOWCASE_MAX_ITERATIONS; i++) {
|
|
299
320
|
|
|
300
321
|
for (let j = 0; j < sourceRects.length; j++) {
|
|
301
322
|
for (let k = 0; k < sourceRects.length; k++) {
|
|
323
|
+
// Iterate through each pair of windows and push apart those windows that intersect
|
|
302
324
|
if (j != k && sourceRects[j].intersectsRect(sourceRects[k])) {
|
|
303
325
|
overlap = YES;
|
|
304
326
|
|
|
@@ -307,11 +329,15 @@ BMWindow.enterShowcase = async function () {
|
|
|
307
329
|
|
|
308
330
|
let difference = rect2.center.pointBySubtractingPoint(rect1.center);
|
|
309
331
|
|
|
332
|
+
// If the windows have the same center point, choose a random direction
|
|
333
|
+
// in which to push them apart
|
|
310
334
|
if (!difference.x && !difference.y) {
|
|
311
335
|
difference.x = Math.random() * 2 - 1;
|
|
312
336
|
difference.y = Math.random() * 2 - 1;
|
|
313
337
|
}
|
|
314
338
|
|
|
339
|
+
// Adjust the direction in which the windows are pushed apart to maintain a similar
|
|
340
|
+
// aspect ratio between the bounds and the viewport
|
|
315
341
|
if (bounds.height / bounds.width > viewportFrame.height / viewportFrame.width) {
|
|
316
342
|
difference.x = difference.x * 2;
|
|
317
343
|
}
|
|
@@ -319,13 +345,16 @@ BMWindow.enterShowcase = async function () {
|
|
|
319
345
|
difference.y = difference.y * 2;
|
|
320
346
|
}
|
|
321
347
|
|
|
348
|
+
// Normalize the distance
|
|
322
349
|
let length = Math.sqrt(difference.x * difference.x + difference.y * difference.y);
|
|
323
350
|
difference.x = difference.x * 20 / length;
|
|
324
351
|
difference.y = difference.y * 20 / length;
|
|
325
352
|
|
|
353
|
+
// Push the two windows apart in opposite directions
|
|
326
354
|
rect1.offsetWithX(-difference.x, {y: -difference.y});
|
|
327
355
|
rect2.offsetWithX(difference.x, {y: difference.y});
|
|
328
356
|
|
|
357
|
+
// Extend the bounds to contain the windows in their new positions
|
|
329
358
|
bounds = bounds.rectByUnionWithRect(rect1).rectByUnionWithRect(rect2);
|
|
330
359
|
|
|
331
360
|
}
|
|
@@ -335,11 +364,14 @@ BMWindow.enterShowcase = async function () {
|
|
|
335
364
|
if (!overlap) break;
|
|
336
365
|
}
|
|
337
366
|
|
|
367
|
+
// Determine how much the windows need to be shrinked to fit on screen
|
|
338
368
|
let scale = Math.min(1, viewportFrame.width / bounds.width, viewportFrame.height / bounds.height);
|
|
339
369
|
|
|
340
370
|
for (let rect of sourceRects) {
|
|
371
|
+
// Adjust the rect's origin so that it is relative to the bounds instead of the viewport
|
|
341
372
|
rect.offset(-bounds.left, -bounds.top);
|
|
342
373
|
|
|
374
|
+
// Apply the scale
|
|
343
375
|
rect.origin.x = rect.origin.x * scale;
|
|
344
376
|
rect.origin.y = rect.origin.y * scale;
|
|
345
377
|
|
|
@@ -351,11 +383,8 @@ BMWindow.enterShowcase = async function () {
|
|
|
351
383
|
BMAnimateWithBlock(() => {
|
|
352
384
|
BMAnimationContextEnableWebAnimations();
|
|
353
385
|
|
|
354
|
-
/*let header = document.getElementById('twStudioHeader');
|
|
355
|
-
let headerController = BMAnimationContextGetCurrent().controllerForObject(header, {node: header});
|
|
356
|
-
headerController.registerBuiltInProperty('translateY', {withValue: -header.offsetHeight + 'px'});*/
|
|
357
|
-
|
|
358
386
|
for (let i = 0; i < sourceRects.length; i++) {
|
|
387
|
+
// For each window, determine which transforms to apply and animate to them
|
|
359
388
|
let transformRect = originalRects[i].rectWithTransformToRect(sourceRects[i]);
|
|
360
389
|
|
|
361
390
|
let controller = BMAnimationContextGetCurrent().controllerForObject(openWindows[i].node, {node: openWindows[i].node});
|
|
@@ -391,19 +420,18 @@ BMWindow.exitShowcase = function (event) {
|
|
|
391
420
|
|
|
392
421
|
BMWindow._isShowcasing = NO;
|
|
393
422
|
|
|
423
|
+
// Clear the event handlers set up for the showcase
|
|
394
424
|
document.body.removeEventListener('click', BMWindow.exitShowcase);
|
|
395
425
|
document.body.removeEventListener('wheel', BMWindow._wheelHandler, YES);
|
|
396
426
|
|
|
397
427
|
let openWindows = BMWindow._windows.filter(value => !value._minimizedWindow);
|
|
398
|
-
/*let twStudio = document.querySelector('#twStudioBody');
|
|
399
|
-
let pageWindow = {node: twStudio};
|
|
400
|
-
openWindows.unshift(pageWindow);*/
|
|
401
428
|
|
|
402
429
|
for (let element of BMWindow._showcaseElements) {
|
|
403
430
|
openWindows.unshift(element);
|
|
404
431
|
}
|
|
405
432
|
|
|
406
433
|
openWindows.forEach(window => {
|
|
434
|
+
// Clear the classes and masks created for each window
|
|
407
435
|
window.node.classList.remove('BMWindowShowcaseWindow');
|
|
408
436
|
|
|
409
437
|
let selector = window.node.querySelector('.BMWindowShowcaseWindowSelector');
|
|
@@ -413,11 +441,8 @@ BMWindow.exitShowcase = function (event) {
|
|
|
413
441
|
BMAnimateWithBlock(() => {
|
|
414
442
|
BMAnimationContextEnableWebAnimations();
|
|
415
443
|
|
|
416
|
-
/*let header = document.getElementById('twStudioHeader');
|
|
417
|
-
let headerController = BMAnimationContextGetCurrent().controllerForObject(header, {node: header});
|
|
418
|
-
headerController.registerBuiltInProperty('translateY', {withValue: '0px'});*/
|
|
419
|
-
|
|
420
444
|
for (let i = 0; i < openWindows.length; i++) {
|
|
445
|
+
// For each window, animate back to no transforms
|
|
421
446
|
let controller = BMAnimationContextGetCurrent().controllerForObject(openWindows[i].node, {node: openWindows[i].node});
|
|
422
447
|
controller.registerBuiltInPropertiesWithDictionary({
|
|
423
448
|
translateX: '0px',
|
|
@@ -1427,6 +1452,7 @@ BMWindow.prototype = BMExtend(Object.create(BMView.prototype), {
|
|
|
1427
1452
|
self._blocker.style.backdropFilter = 'blur(' + ((1 - complete) * 15).toFixed(2) + 'px)';
|
|
1428
1453
|
},*/
|
|
1429
1454
|
complete: function () {
|
|
1455
|
+
self.windowDidClose();
|
|
1430
1456
|
if (self.delegate && self.delegate.windowDidClose) {
|
|
1431
1457
|
self.delegate.windowDidClose(self);
|
|
1432
1458
|
}
|
|
@@ -1467,6 +1493,8 @@ BMWindow.prototype = BMExtend(Object.create(BMView.prototype), {
|
|
|
1467
1493
|
|
|
1468
1494
|
this._window.style.opacity = 0;
|
|
1469
1495
|
this._window.style.display = 'none';
|
|
1496
|
+
|
|
1497
|
+
self.windowDidClose();
|
|
1470
1498
|
|
|
1471
1499
|
if (self.delegate && self.delegate.windowDidClose) {
|
|
1472
1500
|
self.delegate.windowDidClose(self);
|
|
@@ -1475,6 +1503,14 @@ BMWindow.prototype = BMExtend(Object.create(BMView.prototype), {
|
|
|
1475
1503
|
}
|
|
1476
1504
|
},
|
|
1477
1505
|
|
|
1506
|
+
/**
|
|
1507
|
+
* Invoked after this window closes. Subclasses overriding this method must invoked
|
|
1508
|
+
* the superclass method at some point in their implementation.
|
|
1509
|
+
*/
|
|
1510
|
+
windowDidClose() {
|
|
1511
|
+
|
|
1512
|
+
},
|
|
1513
|
+
|
|
1478
1514
|
/**
|
|
1479
1515
|
* Minimizes this window. This method will raise an error if this window is modal.
|
|
1480
1516
|
* If this window is already minimized, this method will have no effect.
|
|
@@ -1793,14 +1829,14 @@ BMWindow.prototype = BMExtend(Object.create(BMView.prototype), {
|
|
|
1793
1829
|
if (BMWindow._keyWindow == this && !this._modal) {
|
|
1794
1830
|
this.node.classList.remove('BMKeyWindow');
|
|
1795
1831
|
this.node.classList.add('BMWindowInactive');
|
|
1796
|
-
if (this.delegate && this.delegate.windowDidResignKeyWindow) {
|
|
1797
|
-
this.delegate.windowDidResignKeyWindow(this);
|
|
1798
|
-
}
|
|
1799
1832
|
BMWindow._keyWindow = undefined;
|
|
1800
1833
|
|
|
1801
1834
|
for (let toolWindow of this._toolWindows) {
|
|
1802
1835
|
toolWindow.hide();
|
|
1803
1836
|
}
|
|
1837
|
+
if (this.delegate && this.delegate.windowDidResignKeyWindow) {
|
|
1838
|
+
this.delegate.windowDidResignKeyWindow(this);
|
|
1839
|
+
}
|
|
1804
1840
|
}
|
|
1805
1841
|
},
|
|
1806
1842
|
|
|
@@ -1867,6 +1903,11 @@ BMWindow.prototype = BMExtend(Object.create(BMView.prototype), {
|
|
|
1867
1903
|
* This instance should not be reused after invoking this method.
|
|
1868
1904
|
*/
|
|
1869
1905
|
release() {
|
|
1906
|
+
if (this.__released) {
|
|
1907
|
+
// This needs to be handled because of the way Thingworx DOM nodes are removed and recreated in the composer
|
|
1908
|
+
return;
|
|
1909
|
+
}
|
|
1910
|
+
|
|
1870
1911
|
if (BMWindow._keyWindow == this) BMWindow._keyWindow = undefined;
|
|
1871
1912
|
|
|
1872
1913
|
if (this._boundViewportDidResize) {
|