bruce-cesium 7.0.9 → 7.1.1
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/dist/bruce-cesium.es5.js +1837 -134
- package/dist/bruce-cesium.es5.js.map +1 -1
- package/dist/bruce-cesium.umd.js +1831 -131
- package/dist/bruce-cesium.umd.js.map +1 -1
- package/dist/lib/bruce-cesium.js +3 -1
- package/dist/lib/bruce-cesium.js.map +1 -1
- package/dist/lib/rendering/visual-register-culler.js +18 -1
- package/dist/lib/rendering/visual-register-culler.js.map +1 -1
- package/dist/lib/utils/entity-utils.js +52 -2
- package/dist/lib/utils/entity-utils.js.map +1 -1
- package/dist/lib/widgets/tabs-left-panel/widget-left-panel-tab-bookmarks.js +427 -63
- package/dist/lib/widgets/tabs-left-panel/widget-left-panel-tab-bookmarks.js.map +1 -1
- package/dist/lib/widgets/tabs-left-panel/widget-left-panel-tab-dashboard.js +507 -0
- package/dist/lib/widgets/tabs-left-panel/widget-left-panel-tab-dashboard.js.map +1 -0
- package/dist/lib/widgets/tabs-left-panel/widget-left-panel-tab-menu-items.js +704 -0
- package/dist/lib/widgets/tabs-left-panel/widget-left-panel-tab-menu-items.js.map +1 -0
- package/dist/lib/widgets/widget-bookmarks.js +9 -7
- package/dist/lib/widgets/widget-bookmarks.js.map +1 -1
- package/dist/lib/widgets/widget-info-view.js +68 -40
- package/dist/lib/widgets/widget-info-view.js.map +1 -1
- package/dist/lib/widgets/widget-left-panel.js +65 -18
- package/dist/lib/widgets/widget-left-panel.js.map +1 -1
- package/dist/types/bruce-cesium.d.ts +3 -1
- package/dist/types/utils/entity-utils.d.ts +11 -0
- package/dist/types/widgets/tabs-left-panel/widget-left-panel-tab-bookmarks.d.ts +14 -0
- package/dist/types/widgets/tabs-left-panel/widget-left-panel-tab-dashboard.d.ts +44 -0
- package/dist/types/widgets/tabs-left-panel/widget-left-panel-tab-menu-items.d.ts +64 -0
- package/dist/types/widgets/widget-left-panel.d.ts +10 -2
- package/package.json +1 -2
|
@@ -0,0 +1,704 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WidgetLeftPanelTabMenuItems = exports.EMenuItemState = void 0;
|
|
4
|
+
const Cesium = require("cesium");
|
|
5
|
+
const bruce_models_1 = require("bruce-models");
|
|
6
|
+
const widget_left_panel_tab_1 = require("./widget-left-panel-tab");
|
|
7
|
+
const entity_utils_1 = require("../../utils/entity-utils");
|
|
8
|
+
/**
|
|
9
|
+
* Enabled state of a menu item row.
|
|
10
|
+
* Folders roll up their children, so they can sit between fully on and fully off.
|
|
11
|
+
*/
|
|
12
|
+
var EMenuItemState;
|
|
13
|
+
(function (EMenuItemState) {
|
|
14
|
+
EMenuItemState["Enabled"] = "enabled";
|
|
15
|
+
EMenuItemState["Disabled"] = "disabled";
|
|
16
|
+
EMenuItemState["ChildEnabled"] = "child-enabled";
|
|
17
|
+
})(EMenuItemState = exports.EMenuItemState || (exports.EMenuItemState = {}));
|
|
18
|
+
// Icons are inline so the library stays dependency free.
|
|
19
|
+
const ICON_CHECK = `<svg viewBox="0 0 11 8" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M1 4L4 7L10 1" stroke="white" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>`;
|
|
20
|
+
const ICON_PARTIAL_CHECK = `<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M8 12H16" stroke="white" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/></svg>`;
|
|
21
|
+
const ICON_CHEV_DOWN = `<svg viewBox="0 0 16 9" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M15 1L8 8L1 1" stroke="white" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>`;
|
|
22
|
+
const ICON_CHEV_RIGHT = `<svg viewBox="0 0 10 17" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M1.5 1.5L8.5 8.5L1.5 15.5" stroke="white" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>`;
|
|
23
|
+
const ICON_FLY_TO = `<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M20.5926 2.12617L2.49072 12.5694C1.78383 12.9756 1.87366 13.9597 2.57664 14.2566L6.72815 15.9984L17.9486 6.10975C18.1634 5.91838 18.468 6.21129 18.2844 6.4339L8.87616 17.8964V21.0403C8.87616 21.962 9.98921 22.3252 10.536 21.6574L13.016 18.6385L17.8822 20.6771C18.4367 20.9115 19.0694 20.5639 19.171 19.9663L21.9829 3.09473C22.1157 2.30583 21.2682 1.73563 20.5926 2.12617Z" fill="white"/></svg>`;
|
|
24
|
+
// Elbow connector drawn instead of a chevron on leaf rows below the root level.
|
|
25
|
+
const ICON_BRACKET = `<svg viewBox="0 0 11 13" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M1 1V10C1 11.1046 1.89543 12 3 12H10" stroke="rgb(131, 141, 150)" stroke-linecap="round" stroke-linejoin="round"/></svg>`;
|
|
26
|
+
// Menu item types backed by a tileset, so a fly-to can fall back to the tileset's bounding sphere.
|
|
27
|
+
const TILESET_TYPES = [
|
|
28
|
+
bruce_models_1.MenuItem.EType.CadTileset,
|
|
29
|
+
bruce_models_1.MenuItem.EType.PointCloud,
|
|
30
|
+
bruce_models_1.MenuItem.EType.EntityTileset,
|
|
31
|
+
bruce_models_1.MenuItem.EType.ArbTileset,
|
|
32
|
+
bruce_models_1.MenuItem.EType.IonTileset,
|
|
33
|
+
bruce_models_1.MenuItem.EType.Osm,
|
|
34
|
+
bruce_models_1.MenuItem.EType.GooglePhotoTileset
|
|
35
|
+
];
|
|
36
|
+
const OPEN_STATE_STORAGE_PREFIX = "NextspaceMenuItemOpen_";
|
|
37
|
+
const PANEL_WIDTH_STORAGE_KEY = "NextspaceMenuItemsPanelWidth";
|
|
38
|
+
// Matches the panel's resize range in the full Navigator experience.
|
|
39
|
+
const PANEL_DEFAULT_WIDTH = 320;
|
|
40
|
+
const PANEL_MIN_WIDTH = 280;
|
|
41
|
+
const PANEL_MAX_WIDTH = 700;
|
|
42
|
+
/**
|
|
43
|
+
* Left panel tab listing the project view's menu items as a checkbox tree.
|
|
44
|
+
* Toggling a row renders or removes that layer in the scene.
|
|
45
|
+
*/
|
|
46
|
+
class WidgetLeftPanelTabMenuItems extends widget_left_panel_tab_1.WidgetLeftPanelTab.ATab {
|
|
47
|
+
constructor(params) {
|
|
48
|
+
var _a, _b, _c, _d;
|
|
49
|
+
super(params);
|
|
50
|
+
this.STYLESHEET_ID = "nextspace-left-panel-tab-menu-items-stylesheet";
|
|
51
|
+
this._menuItems = [];
|
|
52
|
+
this._rows = new Map();
|
|
53
|
+
// Identifies the newest load, so a slow response for an older view can't overwrite a newer one.
|
|
54
|
+
this._loadToken = 0;
|
|
55
|
+
// Rows currently mid fly-to, so a double click doesn't stack camera moves.
|
|
56
|
+
this._flying = new Set();
|
|
57
|
+
this._disposed = false;
|
|
58
|
+
this._generateStyles();
|
|
59
|
+
this._generateElement();
|
|
60
|
+
this._stateQueue = new bruce_models_1.DelayQueue(() => {
|
|
61
|
+
this._updateStates();
|
|
62
|
+
});
|
|
63
|
+
this._countQueue = new bruce_models_1.DelayQueue(() => {
|
|
64
|
+
this._updateCounts();
|
|
65
|
+
});
|
|
66
|
+
this._viewIdChangeRemoval = (_b = (_a = this._widget) === null || _a === void 0 ? void 0 : _a.OnViewIdChange) === null || _b === void 0 ? void 0 : _b.Subscribe(() => {
|
|
67
|
+
this._loadMenuItems();
|
|
68
|
+
});
|
|
69
|
+
const manager = (_c = this._widget) === null || _c === void 0 ? void 0 : _c._getManager();
|
|
70
|
+
if (manager) {
|
|
71
|
+
this._menuUpdateRemoval = manager.OnUpdate.Subscribe(() => {
|
|
72
|
+
this._stateQueue.Call();
|
|
73
|
+
});
|
|
74
|
+
this._visualUpdateRemoval = (_d = manager.VisualsRegister) === null || _d === void 0 ? void 0 : _d.OnUpdate.Subscribe(() => {
|
|
75
|
+
this._countQueue.Call();
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
this._loadMenuItems();
|
|
79
|
+
this._applyPanelWidth(this._getStoredWidth());
|
|
80
|
+
}
|
|
81
|
+
Dispose() {
|
|
82
|
+
var _a, _b, _c, _d, _e;
|
|
83
|
+
this._disposed = true;
|
|
84
|
+
this._endResize();
|
|
85
|
+
// The panel container is shared with the other tabs, so its overrides don't outlive this one.
|
|
86
|
+
if (this.Container) {
|
|
87
|
+
this.Container.style.padding = "";
|
|
88
|
+
}
|
|
89
|
+
(_a = this._viewIdChangeRemoval) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
90
|
+
(_b = this._menuUpdateRemoval) === null || _b === void 0 ? void 0 : _b.call(this);
|
|
91
|
+
(_c = this._visualUpdateRemoval) === null || _c === void 0 ? void 0 : _c.call(this);
|
|
92
|
+
(_d = this._stateQueue) === null || _d === void 0 ? void 0 : _d.Dispose();
|
|
93
|
+
(_e = this._countQueue) === null || _e === void 0 ? void 0 : _e.Dispose();
|
|
94
|
+
this._rows.clear();
|
|
95
|
+
super.Dispose();
|
|
96
|
+
}
|
|
97
|
+
_generateStyles() {
|
|
98
|
+
if (document.getElementById(this.STYLESHEET_ID)) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
const style = document.createElement("style");
|
|
102
|
+
style.id = this.STYLESHEET_ID;
|
|
103
|
+
style.innerHTML = `
|
|
104
|
+
.NextspaceLeftPanelTabMenuItems * {
|
|
105
|
+
box-sizing: border-box;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.NextspaceLeftPanelTabMenuItems {
|
|
109
|
+
color: #fff;
|
|
110
|
+
display: flex;
|
|
111
|
+
flex-direction: column;
|
|
112
|
+
flex-grow: 1;
|
|
113
|
+
flex-shrink: 1;
|
|
114
|
+
font-family: Arial, sans-serif;
|
|
115
|
+
overflow: hidden;
|
|
116
|
+
padding: 30px 20px 12px 20px;
|
|
117
|
+
width: 100%;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.NextspaceLeftPanelTabMenuItems >.NextspaceLeftPanelTabMenuItemsTitleBar {
|
|
121
|
+
align-items: center;
|
|
122
|
+
color: #fff;
|
|
123
|
+
display: flex;
|
|
124
|
+
font-size: 17px;
|
|
125
|
+
font-weight: 500;
|
|
126
|
+
justify-content: center;
|
|
127
|
+
letter-spacing: -.005em;
|
|
128
|
+
line-height: 20px;
|
|
129
|
+
margin-bottom: 15px;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.NextspaceLeftPanelTabMenuItems >.NextspaceLeftPanelTabMenuItemsTitleBreaker {
|
|
133
|
+
background-color: #000;
|
|
134
|
+
flex-shrink: 0;
|
|
135
|
+
height: 2px;
|
|
136
|
+
margin-bottom: 15px;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.NextspaceLeftPanelTabMenuItems >.NextspaceLeftPanelTabMenuItemsScrollBox {
|
|
140
|
+
flex-grow: 1;
|
|
141
|
+
flex-shrink: 1;
|
|
142
|
+
overflow: auto;
|
|
143
|
+
padding-right: 10px;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
.NextspaceLeftPanelTabMenuItems >.NextspaceLeftPanelTabMenuItemsTip {
|
|
147
|
+
color: #fff;
|
|
148
|
+
font-size: 13px;
|
|
149
|
+
opacity: .7;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.NextspaceLeftPanelTabMenuItemsResizeHandle {
|
|
153
|
+
bottom: 0;
|
|
154
|
+
cursor: col-resize;
|
|
155
|
+
position: absolute;
|
|
156
|
+
right: 0;
|
|
157
|
+
top: 0;
|
|
158
|
+
width: 8px;
|
|
159
|
+
z-index: 3;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
.NextspaceMenuItemRow {
|
|
163
|
+
border-bottom: 2px solid #121619;
|
|
164
|
+
width: 100%;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
.NextspaceMenuItemRow[show-children="true"] {
|
|
168
|
+
border-bottom: none;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
.NextspaceMenuItemRow >.NextspaceMenuItemRowItem {
|
|
172
|
+
align-items: center;
|
|
173
|
+
display: flex;
|
|
174
|
+
height: 40px;
|
|
175
|
+
user-select: none;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
.NextspaceMenuItemRow >.NextspaceMenuItemRowItem >.NextspaceMenuItemRowCheckbox,
|
|
179
|
+
.NextspaceMenuItemRow >.NextspaceMenuItemRowItem >.NextspaceMenuItemRowToggle,
|
|
180
|
+
.NextspaceMenuItemRow >.NextspaceMenuItemRowItem >.NextspaceMenuItemRowBracket {
|
|
181
|
+
align-items: center;
|
|
182
|
+
color: #fff;
|
|
183
|
+
cursor: pointer;
|
|
184
|
+
display: flex;
|
|
185
|
+
flex-shrink: 0;
|
|
186
|
+
height: 18px;
|
|
187
|
+
justify-content: center;
|
|
188
|
+
width: 18px;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
.NextspaceMenuItemRow >.NextspaceMenuItemRowItem >.NextspaceMenuItemRowCheckbox >svg,
|
|
192
|
+
.NextspaceMenuItemRow >.NextspaceMenuItemRowItem >.NextspaceMenuItemRowToggle >svg,
|
|
193
|
+
.NextspaceMenuItemRow >.NextspaceMenuItemRowItem >.NextspaceMenuItemRowBracket >svg {
|
|
194
|
+
height: 12px;
|
|
195
|
+
width: 12px;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
.NextspaceMenuItemRow >.NextspaceMenuItemRowItem >.NextspaceMenuItemRowCheckbox {
|
|
199
|
+
border: 1.5px solid #fff;
|
|
200
|
+
border-radius: 2px;
|
|
201
|
+
margin-right: 8px;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
.NextspaceMenuItemRow >.NextspaceMenuItemRowItem >.NextspaceMenuItemRowToggle {
|
|
205
|
+
margin-right: 3px;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
.NextspaceMenuItemRow >.NextspaceMenuItemRowItem >.NextspaceMenuItemRowTitle {
|
|
209
|
+
color: #fff;
|
|
210
|
+
font-size: 14px;
|
|
211
|
+
margin-right: 8px;
|
|
212
|
+
overflow: hidden;
|
|
213
|
+
text-overflow: ellipsis;
|
|
214
|
+
white-space: nowrap;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
.NextspaceMenuItemRow >.NextspaceMenuItemRowItem >.NextspaceMenuItemRowCount {
|
|
218
|
+
background: rgba(0, 175, 250, .2);
|
|
219
|
+
border-radius: 11px;
|
|
220
|
+
color: #18ffff;
|
|
221
|
+
cursor: pointer;
|
|
222
|
+
flex-shrink: 0;
|
|
223
|
+
font-size: 12px;
|
|
224
|
+
margin-right: 3px;
|
|
225
|
+
padding: 5px 8px;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
.NextspaceMenuItemRow >.NextspaceMenuItemRowItem >.NextspaceMenuItemRowQuickBar {
|
|
229
|
+
display: flex;
|
|
230
|
+
flex-shrink: 0;
|
|
231
|
+
margin-left: auto;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
.NextspaceMenuItemRow >.NextspaceMenuItemRowItem >.NextspaceMenuItemRowQuickBar >.NextspaceMenuItemRowQuickBarButton {
|
|
235
|
+
align-items: center;
|
|
236
|
+
cursor: pointer;
|
|
237
|
+
display: flex;
|
|
238
|
+
height: 20px;
|
|
239
|
+
justify-content: center;
|
|
240
|
+
margin-left: 4px;
|
|
241
|
+
opacity: .7;
|
|
242
|
+
transition: .3s ease;
|
|
243
|
+
width: 20px;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
.NextspaceMenuItemRow >.NextspaceMenuItemRowItem >.NextspaceMenuItemRowQuickBar >.NextspaceMenuItemRowQuickBarButton:hover {
|
|
247
|
+
opacity: 1;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
.NextspaceMenuItemRow >.NextspaceMenuItemRowItem >.NextspaceMenuItemRowQuickBar >.NextspaceMenuItemRowQuickBarButton[is-disabled="true"] {
|
|
251
|
+
cursor: default;
|
|
252
|
+
opacity: .3;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
.NextspaceMenuItemRow >.NextspaceMenuItemRowItem >.NextspaceMenuItemRowQuickBar svg {
|
|
256
|
+
height: 18px;
|
|
257
|
+
width: 18px;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
.NextspaceMenuItemRow >.NextspaceMenuItemRowItem[is-enabled="false"] >.NextspaceMenuItemRowCount,
|
|
261
|
+
.NextspaceMenuItemRow >.NextspaceMenuItemRowItem[is-enabled="false"] >.NextspaceMenuItemRowTitle,
|
|
262
|
+
.NextspaceMenuItemRow >.NextspaceMenuItemRowItem[is-enabled="false"] >.NextspaceMenuItemRowCheckbox,
|
|
263
|
+
.NextspaceMenuItemRow >.NextspaceMenuItemRowItem[is-enabled="false"] >.NextspaceMenuItemRowToggle {
|
|
264
|
+
opacity: .5;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
.NextspaceMenuItemRow >.NextspaceMenuItemRowItem[is-enabled="false"] >.NextspaceMenuItemRowQuickBar {
|
|
268
|
+
opacity: 0;
|
|
269
|
+
pointer-events: none;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
.NextspaceMenuItemRow >.NextspaceMenuItemRowDescription {
|
|
273
|
+
font-size: 12px;
|
|
274
|
+
margin: 0 0 8px 0;
|
|
275
|
+
opacity: .7;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
.NextspaceMenuItemRow >.NextspaceMenuItemRowChildren {
|
|
279
|
+
border-top: 2px solid #121619;
|
|
280
|
+
display: flex;
|
|
281
|
+
flex-direction: column;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
.NextspaceMenuItemRow[show-children="false"] >.NextspaceMenuItemRowChildren {
|
|
285
|
+
display: none;
|
|
286
|
+
}
|
|
287
|
+
`;
|
|
288
|
+
document.head.appendChild(style);
|
|
289
|
+
}
|
|
290
|
+
_generateElement() {
|
|
291
|
+
const element = document.createElement("div");
|
|
292
|
+
element.className = "NextspaceLeftPanelTabMenuItems";
|
|
293
|
+
const titleBar = document.createElement("div");
|
|
294
|
+
titleBar.className = "NextspaceLeftPanelTabMenuItemsTitleBar";
|
|
295
|
+
titleBar.textContent = "Menu";
|
|
296
|
+
element.appendChild(titleBar);
|
|
297
|
+
const breaker = document.createElement("div");
|
|
298
|
+
breaker.className = "NextspaceLeftPanelTabMenuItemsTitleBreaker";
|
|
299
|
+
element.appendChild(breaker);
|
|
300
|
+
const tip = document.createElement("div");
|
|
301
|
+
tip.className = "NextspaceLeftPanelTabMenuItemsTip";
|
|
302
|
+
tip.textContent = "Loading...";
|
|
303
|
+
element.appendChild(tip);
|
|
304
|
+
this._tip = tip;
|
|
305
|
+
const scrollBox = document.createElement("div");
|
|
306
|
+
scrollBox.className = "NextspaceLeftPanelTabMenuItemsScrollBox";
|
|
307
|
+
element.appendChild(scrollBox);
|
|
308
|
+
this._scrollBox = scrollBox;
|
|
309
|
+
// Positions against the panel container, which is the nearest positioned ancestor.
|
|
310
|
+
const resizeHandle = document.createElement("div");
|
|
311
|
+
resizeHandle.className = "NextspaceLeftPanelTabMenuItemsResizeHandle";
|
|
312
|
+
resizeHandle.onmousedown = (e) => {
|
|
313
|
+
this._startResize(e);
|
|
314
|
+
};
|
|
315
|
+
element.appendChild(resizeHandle);
|
|
316
|
+
this.Container.appendChild(element);
|
|
317
|
+
this._element = element;
|
|
318
|
+
}
|
|
319
|
+
_getStoredWidth() {
|
|
320
|
+
try {
|
|
321
|
+
const stored = parseInt(window.localStorage.getItem(PANEL_WIDTH_STORAGE_KEY), 10);
|
|
322
|
+
if (!isNaN(stored)) {
|
|
323
|
+
return stored;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
catch (e) {
|
|
327
|
+
// Storage can be unavailable (private mode, blocked cookies). The default width still works.
|
|
328
|
+
}
|
|
329
|
+
return PANEL_DEFAULT_WIDTH;
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Sizes the shared panel container to this tab's width, clamped to the allowed range.
|
|
333
|
+
*/
|
|
334
|
+
_applyPanelWidth(width) {
|
|
335
|
+
const clamped = Math.min(PANEL_MAX_WIDTH, Math.max(PANEL_MIN_WIDTH, width));
|
|
336
|
+
if (this.Container) {
|
|
337
|
+
this.Container.style.width = clamped + "px";
|
|
338
|
+
// Padding lives on this tab's own element instead, so the resize handle can reach the panel edge.
|
|
339
|
+
this.Container.style.padding = "0";
|
|
340
|
+
}
|
|
341
|
+
return clamped;
|
|
342
|
+
}
|
|
343
|
+
_startResize(e) {
|
|
344
|
+
e.preventDefault();
|
|
345
|
+
const startX = e.clientX;
|
|
346
|
+
const startWidth = this.Container ? this.Container.offsetWidth : PANEL_DEFAULT_WIDTH;
|
|
347
|
+
this._onResizeMove = (moveEvent) => {
|
|
348
|
+
this._applyPanelWidth(startWidth + (moveEvent.clientX - startX));
|
|
349
|
+
};
|
|
350
|
+
this._onResizeUp = () => {
|
|
351
|
+
const finalWidth = this._applyPanelWidth(this.Container ? this.Container.offsetWidth : PANEL_DEFAULT_WIDTH);
|
|
352
|
+
try {
|
|
353
|
+
window.localStorage.setItem(PANEL_WIDTH_STORAGE_KEY, String(finalWidth));
|
|
354
|
+
}
|
|
355
|
+
catch (err) {
|
|
356
|
+
console.warn(err);
|
|
357
|
+
}
|
|
358
|
+
this._endResize();
|
|
359
|
+
};
|
|
360
|
+
window.addEventListener("mousemove", this._onResizeMove);
|
|
361
|
+
window.addEventListener("mouseup", this._onResizeUp);
|
|
362
|
+
}
|
|
363
|
+
_endResize() {
|
|
364
|
+
if (this._onResizeMove) {
|
|
365
|
+
window.removeEventListener("mousemove", this._onResizeMove);
|
|
366
|
+
this._onResizeMove = null;
|
|
367
|
+
}
|
|
368
|
+
if (this._onResizeUp) {
|
|
369
|
+
window.removeEventListener("mouseup", this._onResizeUp);
|
|
370
|
+
this._onResizeUp = null;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
async _loadMenuItems() {
|
|
374
|
+
var _a, _b, _c, _d;
|
|
375
|
+
const viewId = (_a = this._widget) === null || _a === void 0 ? void 0 : _a.ViewId;
|
|
376
|
+
const token = ++this._loadToken;
|
|
377
|
+
let menuItems = [];
|
|
378
|
+
try {
|
|
379
|
+
if (viewId) {
|
|
380
|
+
const api = (_b = this._widget._getApiGetters()) === null || _b === void 0 ? void 0 : _b.GetBruceApi();
|
|
381
|
+
const data = await bruce_models_1.ProjectView.Get({
|
|
382
|
+
viewId,
|
|
383
|
+
api
|
|
384
|
+
});
|
|
385
|
+
const settings = (_c = data === null || data === void 0 ? void 0 : data.view) === null || _c === void 0 ? void 0 : _c.Settings;
|
|
386
|
+
menuItems = (_d = settings === null || settings === void 0 ? void 0 : settings.menuItems) !== null && _d !== void 0 ? _d : [];
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
catch (e) {
|
|
390
|
+
console.error(e);
|
|
391
|
+
menuItems = [];
|
|
392
|
+
}
|
|
393
|
+
if (this._disposed || token !== this._loadToken) {
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
this._menuItems = menuItems;
|
|
397
|
+
this._renderTree();
|
|
398
|
+
this._updateStates();
|
|
399
|
+
this._updateCounts();
|
|
400
|
+
}
|
|
401
|
+
_renderTree() {
|
|
402
|
+
var _a;
|
|
403
|
+
this._rows.clear();
|
|
404
|
+
this._scrollBox.innerHTML = "";
|
|
405
|
+
if (!this._menuItems.length) {
|
|
406
|
+
// The panel can be opened before any view has rendered, so say so rather than claiming it's empty.
|
|
407
|
+
this._tip.textContent = ((_a = this._widget) === null || _a === void 0 ? void 0 : _a.ViewId)
|
|
408
|
+
? "This project view has no menu items."
|
|
409
|
+
: "Waiting for a view to load...";
|
|
410
|
+
this._tip.style.display = "block";
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
413
|
+
this._tip.style.display = "none";
|
|
414
|
+
for (const item of this._menuItems) {
|
|
415
|
+
this._renderRow(item, 0, this._scrollBox);
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
_renderRow(item, depth, parent) {
|
|
419
|
+
var _a;
|
|
420
|
+
if (!(item === null || item === void 0 ? void 0 : item.id)) {
|
|
421
|
+
return;
|
|
422
|
+
}
|
|
423
|
+
const isFolder = !item.Type || item.Type === bruce_models_1.MenuItem.EType.None;
|
|
424
|
+
const children = item.hideChildren ? [] : ((_a = item.Children) !== null && _a !== void 0 ? _a : []);
|
|
425
|
+
const hasChildren = children.length > 0;
|
|
426
|
+
const row = document.createElement("div");
|
|
427
|
+
row.className = "NextspaceMenuItemRow";
|
|
428
|
+
row.setAttribute("menu-item-id", item.id);
|
|
429
|
+
const itemElement = document.createElement("div");
|
|
430
|
+
itemElement.className = "NextspaceMenuItemRowItem";
|
|
431
|
+
itemElement.style.paddingLeft = (depth * 15) + "px";
|
|
432
|
+
row.appendChild(itemElement);
|
|
433
|
+
if (hasChildren) {
|
|
434
|
+
const toggle = document.createElement("div");
|
|
435
|
+
toggle.className = "NextspaceMenuItemRowToggle";
|
|
436
|
+
toggle.onclick = () => {
|
|
437
|
+
this._setOpen(item.id, depth, row.getAttribute("show-children") !== "true", row, toggle);
|
|
438
|
+
};
|
|
439
|
+
itemElement.appendChild(toggle);
|
|
440
|
+
const opened = this._getOpen(item.id, depth);
|
|
441
|
+
row.setAttribute("show-children", opened ? "true" : "false");
|
|
442
|
+
toggle.innerHTML = opened ? ICON_CHEV_DOWN : ICON_CHEV_RIGHT;
|
|
443
|
+
}
|
|
444
|
+
else if (depth > 0) {
|
|
445
|
+
const bracket = document.createElement("div");
|
|
446
|
+
bracket.className = "NextspaceMenuItemRowBracket";
|
|
447
|
+
bracket.innerHTML = ICON_BRACKET;
|
|
448
|
+
itemElement.appendChild(bracket);
|
|
449
|
+
row.setAttribute("show-children", "false");
|
|
450
|
+
}
|
|
451
|
+
else {
|
|
452
|
+
row.setAttribute("show-children", "false");
|
|
453
|
+
}
|
|
454
|
+
const checkbox = document.createElement("div");
|
|
455
|
+
checkbox.className = "NextspaceMenuItemRowCheckbox";
|
|
456
|
+
checkbox.onclick = () => {
|
|
457
|
+
this._toggleItem(item);
|
|
458
|
+
};
|
|
459
|
+
itemElement.appendChild(checkbox);
|
|
460
|
+
const title = document.createElement("div");
|
|
461
|
+
title.className = "NextspaceMenuItemRowTitle";
|
|
462
|
+
title.textContent = item.Caption || "Unnamed Menu Item";
|
|
463
|
+
title.title = item.Caption || "Unnamed Menu Item";
|
|
464
|
+
itemElement.appendChild(title);
|
|
465
|
+
// Folders have no visuals of their own, so a count would always read zero.
|
|
466
|
+
let count = null;
|
|
467
|
+
if (!isFolder) {
|
|
468
|
+
count = document.createElement("div");
|
|
469
|
+
count.className = "NextspaceMenuItemRowCount";
|
|
470
|
+
count.style.display = "none";
|
|
471
|
+
count.onclick = () => {
|
|
472
|
+
this._selectItemEntities(item);
|
|
473
|
+
};
|
|
474
|
+
itemElement.appendChild(count);
|
|
475
|
+
}
|
|
476
|
+
const quickBar = document.createElement("div");
|
|
477
|
+
quickBar.className = "NextspaceMenuItemRowQuickBar";
|
|
478
|
+
itemElement.appendChild(quickBar);
|
|
479
|
+
if (!isFolder) {
|
|
480
|
+
const flyTo = document.createElement("div");
|
|
481
|
+
flyTo.className = "NextspaceMenuItemRowQuickBarButton";
|
|
482
|
+
flyTo.title = "Fly to";
|
|
483
|
+
flyTo.innerHTML = ICON_FLY_TO;
|
|
484
|
+
flyTo.onclick = () => {
|
|
485
|
+
this._flyToItem(item, flyTo);
|
|
486
|
+
};
|
|
487
|
+
quickBar.appendChild(flyTo);
|
|
488
|
+
}
|
|
489
|
+
if (item.Description) {
|
|
490
|
+
const description = document.createElement("p");
|
|
491
|
+
description.className = "NextspaceMenuItemRowDescription";
|
|
492
|
+
description.style.paddingLeft = (depth * 15) + "px";
|
|
493
|
+
description.textContent = item.Description;
|
|
494
|
+
row.appendChild(description);
|
|
495
|
+
}
|
|
496
|
+
const childrenElement = document.createElement("div");
|
|
497
|
+
childrenElement.className = "NextspaceMenuItemRowChildren";
|
|
498
|
+
row.appendChild(childrenElement);
|
|
499
|
+
parent.appendChild(row);
|
|
500
|
+
this._rows.set(item.id, {
|
|
501
|
+
item,
|
|
502
|
+
depth,
|
|
503
|
+
element: row,
|
|
504
|
+
itemElement,
|
|
505
|
+
checkboxElement: checkbox,
|
|
506
|
+
countElement: count,
|
|
507
|
+
childrenElement
|
|
508
|
+
});
|
|
509
|
+
for (const child of children) {
|
|
510
|
+
this._renderRow(child, depth + 1, childrenElement);
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
_getOpen(itemId, depth) {
|
|
514
|
+
try {
|
|
515
|
+
return window.localStorage.getItem(OPEN_STATE_STORAGE_PREFIX + itemId + depth) === "true";
|
|
516
|
+
}
|
|
517
|
+
catch (e) {
|
|
518
|
+
// Storage can be unavailable (private mode, blocked cookies). Not worth failing the tree over.
|
|
519
|
+
return false;
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
_setOpen(itemId, depth, open, row, toggle) {
|
|
523
|
+
row.setAttribute("show-children", open ? "true" : "false");
|
|
524
|
+
toggle.innerHTML = open ? ICON_CHEV_DOWN : ICON_CHEV_RIGHT;
|
|
525
|
+
try {
|
|
526
|
+
window.localStorage.setItem(OPEN_STATE_STORAGE_PREFIX + itemId + depth, open ? "true" : "false");
|
|
527
|
+
}
|
|
528
|
+
catch (e) {
|
|
529
|
+
console.warn(e);
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
/**
|
|
533
|
+
* Resolves each row's state from what the manager currently has rendered.
|
|
534
|
+
*/
|
|
535
|
+
_updateStates() {
|
|
536
|
+
var _a;
|
|
537
|
+
const manager = (_a = this._widget) === null || _a === void 0 ? void 0 : _a._getManager();
|
|
538
|
+
if (!manager || this._disposed) {
|
|
539
|
+
return;
|
|
540
|
+
}
|
|
541
|
+
const enabledIds = new Set(manager.GetEnabledItemIds());
|
|
542
|
+
for (const row of Array.from(this._rows.values())) {
|
|
543
|
+
const state = this._resolveState(row.item, enabledIds);
|
|
544
|
+
row.itemElement.setAttribute("is-enabled", state === EMenuItemState.Disabled ? "false" : "true");
|
|
545
|
+
if (state === EMenuItemState.Enabled) {
|
|
546
|
+
row.checkboxElement.innerHTML = ICON_CHECK;
|
|
547
|
+
}
|
|
548
|
+
else if (state === EMenuItemState.ChildEnabled) {
|
|
549
|
+
row.checkboxElement.innerHTML = ICON_PARTIAL_CHECK;
|
|
550
|
+
}
|
|
551
|
+
else {
|
|
552
|
+
row.checkboxElement.innerHTML = "";
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
/**
|
|
557
|
+
* Works out a single item's state, rolling up children so a folder can report a partial state.
|
|
558
|
+
*/
|
|
559
|
+
_resolveState(item, enabledIds) {
|
|
560
|
+
var _a;
|
|
561
|
+
const isFolder = !item.Type || item.Type === bruce_models_1.MenuItem.EType.None;
|
|
562
|
+
if (!isFolder) {
|
|
563
|
+
return enabledIds.has(item.id) ? EMenuItemState.Enabled : EMenuItemState.Disabled;
|
|
564
|
+
}
|
|
565
|
+
// Folders derive from the leaves below them rather than their own enabled flag.
|
|
566
|
+
let actionCount = 0;
|
|
567
|
+
let enabledActionCount = 0;
|
|
568
|
+
const traverse = (current) => {
|
|
569
|
+
var _a;
|
|
570
|
+
const currentIsFolder = !current.Type || current.Type === bruce_models_1.MenuItem.EType.None;
|
|
571
|
+
if (!currentIsFolder) {
|
|
572
|
+
actionCount += 1;
|
|
573
|
+
if (enabledIds.has(current.id)) {
|
|
574
|
+
enabledActionCount += 1;
|
|
575
|
+
}
|
|
576
|
+
return;
|
|
577
|
+
}
|
|
578
|
+
if ((_a = current.Children) === null || _a === void 0 ? void 0 : _a.length) {
|
|
579
|
+
current.Children.forEach(traverse);
|
|
580
|
+
}
|
|
581
|
+
};
|
|
582
|
+
(_a = item.Children) === null || _a === void 0 ? void 0 : _a.forEach(traverse);
|
|
583
|
+
if (actionCount <= 0) {
|
|
584
|
+
return enabledIds.has(item.id) ? EMenuItemState.Enabled : EMenuItemState.Disabled;
|
|
585
|
+
}
|
|
586
|
+
if (enabledActionCount <= 0) {
|
|
587
|
+
return EMenuItemState.Disabled;
|
|
588
|
+
}
|
|
589
|
+
return enabledActionCount >= actionCount ? EMenuItemState.Enabled : EMenuItemState.ChildEnabled;
|
|
590
|
+
}
|
|
591
|
+
_updateCounts() {
|
|
592
|
+
var _a, _b;
|
|
593
|
+
const register = (_b = (_a = this._widget) === null || _a === void 0 ? void 0 : _a._getManager()) === null || _b === void 0 ? void 0 : _b.VisualsRegister;
|
|
594
|
+
if (!register || this._disposed) {
|
|
595
|
+
return;
|
|
596
|
+
}
|
|
597
|
+
for (const row of Array.from(this._rows.values())) {
|
|
598
|
+
if (!row.countElement) {
|
|
599
|
+
continue;
|
|
600
|
+
}
|
|
601
|
+
const count = register.GetRegos({
|
|
602
|
+
menuItemId: row.item.id
|
|
603
|
+
}).length;
|
|
604
|
+
row.countElement.style.display = count > 0 ? "block" : "none";
|
|
605
|
+
row.countElement.textContent = count.toLocaleString();
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
_toggleItem(item) {
|
|
609
|
+
var _a;
|
|
610
|
+
const manager = (_a = this._widget) === null || _a === void 0 ? void 0 : _a._getManager();
|
|
611
|
+
if (!manager) {
|
|
612
|
+
return;
|
|
613
|
+
}
|
|
614
|
+
const enabledIds = new Set(manager.GetEnabledItemIds());
|
|
615
|
+
const state = this._resolveState(item, enabledIds);
|
|
616
|
+
if (state === EMenuItemState.Enabled) {
|
|
617
|
+
this._disableItem(item);
|
|
618
|
+
}
|
|
619
|
+
else {
|
|
620
|
+
manager.RenderItem({
|
|
621
|
+
item
|
|
622
|
+
});
|
|
623
|
+
}
|
|
624
|
+
this._stateQueue.Call(true);
|
|
625
|
+
}
|
|
626
|
+
_disableItem(item) {
|
|
627
|
+
var _a, _b;
|
|
628
|
+
const manager = (_a = this._widget) === null || _a === void 0 ? void 0 : _a._getManager();
|
|
629
|
+
if (!manager) {
|
|
630
|
+
return;
|
|
631
|
+
}
|
|
632
|
+
if ((_b = item.Children) === null || _b === void 0 ? void 0 : _b.length) {
|
|
633
|
+
item.Children.forEach((child) => this._disableItem(child));
|
|
634
|
+
}
|
|
635
|
+
manager.RemoveItemById({
|
|
636
|
+
menuItemId: item.id
|
|
637
|
+
});
|
|
638
|
+
}
|
|
639
|
+
_selectItemEntities(item) {
|
|
640
|
+
var _a, _b;
|
|
641
|
+
const register = (_b = (_a = this._widget) === null || _a === void 0 ? void 0 : _a._getManager()) === null || _b === void 0 ? void 0 : _b.VisualsRegister;
|
|
642
|
+
if (!register) {
|
|
643
|
+
return;
|
|
644
|
+
}
|
|
645
|
+
const entityIds = register.GetRegos({
|
|
646
|
+
menuItemId: item.id
|
|
647
|
+
}).map(x => x.entityId);
|
|
648
|
+
if (!entityIds.length) {
|
|
649
|
+
return;
|
|
650
|
+
}
|
|
651
|
+
register.ClearSelected();
|
|
652
|
+
register.SetSelected({
|
|
653
|
+
selected: true,
|
|
654
|
+
entityIds,
|
|
655
|
+
menuItemId: item.id
|
|
656
|
+
});
|
|
657
|
+
}
|
|
658
|
+
/**
|
|
659
|
+
* Flies the camera to a menu item's contents.
|
|
660
|
+
* Tileset-backed items fall back to the tileset's own bounds when no entity visuals are registered.
|
|
661
|
+
*/
|
|
662
|
+
async _flyToItem(item, button) {
|
|
663
|
+
var _a, _b, _c, _d;
|
|
664
|
+
if (this._flying.has(item.id)) {
|
|
665
|
+
return;
|
|
666
|
+
}
|
|
667
|
+
const manager = (_a = this._widget) === null || _a === void 0 ? void 0 : _a._getManager();
|
|
668
|
+
const viewer = (_b = this._widget) === null || _b === void 0 ? void 0 : _b._getViewer();
|
|
669
|
+
if (!manager || !viewer) {
|
|
670
|
+
return;
|
|
671
|
+
}
|
|
672
|
+
this._flying.add(item.id);
|
|
673
|
+
button.setAttribute("is-disabled", "true");
|
|
674
|
+
try {
|
|
675
|
+
const regos = manager.VisualsRegister.GetRegos({
|
|
676
|
+
menuItemId: item.id
|
|
677
|
+
}).filter(x => !!(x === null || x === void 0 ? void 0 : x.visual) && !(x.visual instanceof Cesium.Cesium3DTileFeature));
|
|
678
|
+
let tileset = null;
|
|
679
|
+
if (!regos.length && TILESET_TYPES.indexOf(item.Type) >= 0) {
|
|
680
|
+
const enabled = manager.GetEnabledItem(item.id);
|
|
681
|
+
tileset = (_d = (_c = enabled === null || enabled === void 0 ? void 0 : enabled.renderManager) === null || _c === void 0 ? void 0 : _c.Tileset) !== null && _d !== void 0 ? _d : null;
|
|
682
|
+
}
|
|
683
|
+
const entityIds = regos.map(x => x.entityId);
|
|
684
|
+
if (!entityIds.length && !tileset) {
|
|
685
|
+
return;
|
|
686
|
+
}
|
|
687
|
+
await entity_utils_1.EntityUtils.FlyTo({
|
|
688
|
+
viewer,
|
|
689
|
+
manager,
|
|
690
|
+
entityIds: entityIds.length ? entityIds : null,
|
|
691
|
+
tileset
|
|
692
|
+
});
|
|
693
|
+
}
|
|
694
|
+
catch (e) {
|
|
695
|
+
console.error(e);
|
|
696
|
+
}
|
|
697
|
+
finally {
|
|
698
|
+
this._flying.delete(item.id);
|
|
699
|
+
button.setAttribute("is-disabled", "false");
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
exports.WidgetLeftPanelTabMenuItems = WidgetLeftPanelTabMenuItems;
|
|
704
|
+
//# sourceMappingURL=widget-left-panel-tab-menu-items.js.map
|