@itwin/editor-frontend 3.6.0-dev.8 → 3.6.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.
Files changed (98) hide show
  1. package/CHANGELOG.md +34 -1
  2. package/LICENSE.md +1 -1
  3. package/lib/cjs/CreateElementTool.d.ts +100 -100
  4. package/lib/cjs/CreateElementTool.js +327 -327
  5. package/lib/cjs/CreateElementTool.js.map +1 -1
  6. package/lib/cjs/DeleteElementsTool.d.ts +13 -13
  7. package/lib/cjs/DeleteElementsTool.js +38 -38
  8. package/lib/cjs/DeleteElementsTool.js.map +1 -1
  9. package/lib/cjs/EditTool.d.ts +38 -36
  10. package/lib/cjs/EditTool.d.ts.map +1 -1
  11. package/lib/cjs/EditTool.js +81 -135
  12. package/lib/cjs/EditTool.js.map +1 -1
  13. package/lib/cjs/EditToolIpc.d.ts +18 -17
  14. package/lib/cjs/EditToolIpc.d.ts.map +1 -1
  15. package/lib/cjs/EditToolIpc.js +28 -27
  16. package/lib/cjs/EditToolIpc.js.map +1 -1
  17. package/lib/cjs/ElementGeometryTool.d.ts +147 -147
  18. package/lib/cjs/ElementGeometryTool.js +709 -709
  19. package/lib/cjs/ElementGeometryTool.js.map +1 -1
  20. package/lib/cjs/ModifyCurveTools.d.ts +139 -139
  21. package/lib/cjs/ModifyCurveTools.js +784 -784
  22. package/lib/cjs/ModifyCurveTools.js.map +1 -1
  23. package/lib/cjs/ModifyElementTool.d.ts +47 -47
  24. package/lib/cjs/ModifyElementTool.js +177 -177
  25. package/lib/cjs/ModifyElementTool.js.map +1 -1
  26. package/lib/cjs/ProjectLocation/ProjectExtentsDecoration.d.ts +135 -135
  27. package/lib/cjs/ProjectLocation/ProjectExtentsDecoration.js +822 -822
  28. package/lib/cjs/ProjectLocation/ProjectExtentsDecoration.js.map +1 -1
  29. package/lib/cjs/ProjectLocation/ProjectGeolocation.d.ts +135 -135
  30. package/lib/cjs/ProjectLocation/ProjectGeolocation.js +532 -532
  31. package/lib/cjs/ProjectLocation/ProjectGeolocation.js.map +1 -1
  32. package/lib/cjs/SketchTools.d.ts +304 -304
  33. package/lib/cjs/SketchTools.js +1705 -1705
  34. package/lib/cjs/SketchTools.js.map +1 -1
  35. package/lib/cjs/SolidModelingTools.d.ts +380 -380
  36. package/lib/cjs/SolidModelingTools.js +1462 -1462
  37. package/lib/cjs/SolidModelingTools.js.map +1 -1
  38. package/lib/cjs/SolidPrimitiveTools.d.ts +318 -318
  39. package/lib/cjs/SolidPrimitiveTools.js +1378 -1378
  40. package/lib/cjs/SolidPrimitiveTools.js.map +1 -1
  41. package/lib/cjs/TransformElementsTool.d.ts +164 -164
  42. package/lib/cjs/TransformElementsTool.js +652 -652
  43. package/lib/cjs/TransformElementsTool.js.map +1 -1
  44. package/lib/cjs/UndoRedoTool.d.ts +16 -16
  45. package/lib/cjs/UndoRedoTool.js +42 -42
  46. package/lib/cjs/UndoRedoTool.js.map +1 -1
  47. package/lib/cjs/editor-frontend.d.ts +17 -17
  48. package/lib/cjs/editor-frontend.js +33 -33
  49. package/lib/cjs/editor-frontend.js.map +1 -1
  50. package/lib/esm/CreateElementTool.d.ts +100 -100
  51. package/lib/esm/CreateElementTool.js +319 -319
  52. package/lib/esm/CreateElementTool.js.map +1 -1
  53. package/lib/esm/DeleteElementsTool.d.ts +13 -13
  54. package/lib/esm/DeleteElementsTool.js +34 -34
  55. package/lib/esm/DeleteElementsTool.js.map +1 -1
  56. package/lib/esm/EditTool.d.ts +38 -36
  57. package/lib/esm/EditTool.d.ts.map +1 -1
  58. package/lib/esm/EditTool.js +77 -131
  59. package/lib/esm/EditTool.js.map +1 -1
  60. package/lib/esm/EditToolIpc.d.ts +18 -17
  61. package/lib/esm/EditToolIpc.d.ts.map +1 -1
  62. package/lib/esm/EditToolIpc.js +24 -23
  63. package/lib/esm/EditToolIpc.js.map +1 -1
  64. package/lib/esm/ElementGeometryTool.d.ts +147 -147
  65. package/lib/esm/ElementGeometryTool.js +701 -701
  66. package/lib/esm/ElementGeometryTool.js.map +1 -1
  67. package/lib/esm/ModifyCurveTools.d.ts +139 -139
  68. package/lib/esm/ModifyCurveTools.js +775 -775
  69. package/lib/esm/ModifyCurveTools.js.map +1 -1
  70. package/lib/esm/ModifyElementTool.d.ts +47 -47
  71. package/lib/esm/ModifyElementTool.js +172 -172
  72. package/lib/esm/ModifyElementTool.js.map +1 -1
  73. package/lib/esm/ProjectLocation/ProjectExtentsDecoration.d.ts +135 -135
  74. package/lib/esm/ProjectLocation/ProjectExtentsDecoration.js +814 -814
  75. package/lib/esm/ProjectLocation/ProjectExtentsDecoration.js.map +1 -1
  76. package/lib/esm/ProjectLocation/ProjectGeolocation.d.ts +135 -135
  77. package/lib/esm/ProjectLocation/ProjectGeolocation.js +526 -526
  78. package/lib/esm/ProjectLocation/ProjectGeolocation.js.map +1 -1
  79. package/lib/esm/SketchTools.d.ts +304 -304
  80. package/lib/esm/SketchTools.js +1695 -1695
  81. package/lib/esm/SketchTools.js.map +1 -1
  82. package/lib/esm/SolidModelingTools.d.ts +380 -380
  83. package/lib/esm/SolidModelingTools.js +1437 -1437
  84. package/lib/esm/SolidModelingTools.js.map +1 -1
  85. package/lib/esm/SolidPrimitiveTools.d.ts +318 -318
  86. package/lib/esm/SolidPrimitiveTools.js +1367 -1367
  87. package/lib/esm/SolidPrimitiveTools.js.map +1 -1
  88. package/lib/esm/TransformElementsTool.d.ts +164 -164
  89. package/lib/esm/TransformElementsTool.js +644 -644
  90. package/lib/esm/TransformElementsTool.js.map +1 -1
  91. package/lib/esm/UndoRedoTool.d.ts +16 -16
  92. package/lib/esm/UndoRedoTool.js +36 -36
  93. package/lib/esm/UndoRedoTool.js.map +1 -1
  94. package/lib/esm/editor-frontend.d.ts +17 -17
  95. package/lib/esm/editor-frontend.js +21 -21
  96. package/lib/esm/editor-frontend.js.map +1 -1
  97. package/lib/public/locales/en/Editor.json +490 -490
  98. package/package.json +15 -15
@@ -1,533 +1,533 @@
1
- "use strict";
2
- /*---------------------------------------------------------------------------------------------
3
- * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
4
- * See LICENSE.md in the project root for license terms and full copyright notice.
5
- *--------------------------------------------------------------------------------------------*/
6
- /** @packageDocumentation
7
- * @module Editing
8
- */
9
- Object.defineProperty(exports, "__esModule", { value: true });
10
- exports.ProjectGeolocationMoveTool = exports.ProjectGeolocationNorthTool = exports.ProjectGeolocationPointTool = void 0;
11
- const core_frontend_1 = require("@itwin/core-frontend");
12
- const core_geometry_1 = require("@itwin/core-geometry");
13
- const core_common_1 = require("@itwin/core-common");
14
- const ProjectExtentsDecoration_1 = require("./ProjectExtentsDecoration");
15
- const appui_abstract_1 = require("@itwin/appui-abstract");
16
- const EditTool_1 = require("../EditTool");
17
- function translatePrompt(key) {
18
- return EditTool_1.EditTools.translate(`ProjectLocation:Prompts.${key}`);
19
- }
20
- function translateMessage(key) {
21
- return EditTool_1.EditTools.translate(`ProjectLocation:Message.${key}`);
22
- }
23
- /** @internal */
24
- class LabelDecoration {
25
- constructor(worldLocation, label) {
26
- this.worldLocation = new core_geometry_1.Point3d();
27
- this.position = new core_geometry_1.Point3d();
28
- this.worldLocation.setFrom(worldLocation);
29
- this.label = label;
30
- }
31
- drawDecoration(ctx) {
32
- ctx.font = "16px san-serif";
33
- const labelHeight = ctx.measureText("M").width; // Close enough for border padding...
34
- const labelWidth = ctx.measureText(this.label).width + labelHeight;
35
- ctx.lineWidth = 1;
36
- ctx.strokeStyle = "white";
37
- ctx.fillStyle = "rgba(0,0,0,.4)";
38
- ctx.shadowColor = "black";
39
- ctx.shadowBlur = 10;
40
- ctx.fillRect(-(labelWidth / 2), -labelHeight, labelWidth, labelHeight * 2);
41
- ctx.strokeRect(-(labelWidth / 2), -labelHeight, labelWidth, labelHeight * 2);
42
- ctx.fillStyle = "white";
43
- ctx.shadowBlur = 0;
44
- ctx.textAlign = "center";
45
- ctx.textBaseline = "middle";
46
- ctx.fillText(this.label, 0, 0);
47
- }
48
- setPosition(vp) {
49
- vp.worldToView(this.worldLocation, this.position);
50
- this.position.y -= Math.floor(vp.pixelsFromInches(0.45)) + 0.5; // Offset from world location...
51
- return vp.viewRect.containsPoint(this.position);
52
- }
53
- addDecoration(context) {
54
- if (this.setPosition(context.viewport))
55
- context.addCanvasDecoration(this);
56
- }
57
- }
58
- /** Change or update geolocation for project.
59
- * To show tool settings for specifying lat/long, make sure formatting and parsing data are cached before the tool starts
60
- * by calling QuantityFormatter.onInitialized at app startup.
61
- * @beta
62
- */
63
- class ProjectGeolocationPointTool extends core_frontend_1.PrimitiveTool {
64
- constructor() {
65
- super(...arguments);
66
- this._haveToolSettings = false;
67
- this._cartographicFromArgs = false;
68
- this._accept = false;
69
- this._scale = 1.0;
70
- }
71
- static get minArgs() { return 0; }
72
- static get maxArgs() { return 4; } // latitude, longitude, altitude, north direction...
73
- isCompatibleViewport(vp, isSelectedViewChange) { return (super.isCompatibleViewport(vp, isSelectedViewChange) && undefined !== vp && vp.view.isSpatialView()); }
74
- isValidLocation(_ev, _isButtonEvent) { return true; } // Allow snapping to terrain, etc. outside project extents...
75
- requireWriteableTarget() { return false; } // Tool doesn't modify the imodel...
76
- async onPostInstall() {
77
- await super.onPostInstall();
78
- this.setupAndPromptForNextAction();
79
- }
80
- async onCleanup() {
81
- await super.onCleanup();
82
- this.unsuspendDecorations();
83
- }
84
- async onRestartTool() { return this.exitTool(); }
85
- async onUnsuspend() { this.provideToolAssistance(); }
86
- get latitudeProperty() {
87
- if (!this._latitudeProperty)
88
- this._latitudeProperty = new appui_abstract_1.DialogProperty(new core_frontend_1.AngleDescription("latitude", translateMessage("Latitude")), 0.0);
89
- return this._latitudeProperty;
90
- }
91
- get latitude() { return this.latitudeProperty.value; }
92
- set latitude(value) { this.latitudeProperty.value = value; }
93
- get longitudeProperty() {
94
- if (!this._longitudeProperty)
95
- this._longitudeProperty = new appui_abstract_1.DialogProperty(new core_frontend_1.AngleDescription("longitude", translateMessage("Longitude")), 0.0);
96
- return this._longitudeProperty;
97
- }
98
- get longitude() { return this.longitudeProperty.value; }
99
- set longitude(value) { this.longitudeProperty.value = value; }
100
- get altitudeProperty() {
101
- if (!this._altitudeProperty)
102
- this._altitudeProperty = new appui_abstract_1.DialogProperty(new core_frontend_1.LengthDescription("altitude", core_frontend_1.CoreTools.translate("Measure.Labels.Altitude")), 0.0);
103
- return this._altitudeProperty;
104
- }
105
- get altitude() { return this.altitudeProperty.value; }
106
- set altitude(value) { this.altitudeProperty.value = value; }
107
- get northProperty() {
108
- if (!this._northProperty)
109
- this._northProperty = new appui_abstract_1.DialogProperty(new core_frontend_1.AngleDescription("north", translateMessage("North")), 0.0);
110
- return this._northProperty;
111
- }
112
- get north() { return this.northProperty.value; }
113
- set north(value) { this.northProperty.value = value; }
114
- syncToolSettingsCoordinates() {
115
- this.syncToolSettingsProperties([this.latitudeProperty.syncItem, this.longitudeProperty.syncItem, this.altitudeProperty.syncItem, this.northProperty.syncItem]);
116
- }
117
- async applyToolSettingPropertyChange(updatedValue) {
118
- return this.changeToolSettingPropertyValue(updatedValue);
119
- }
120
- supplyToolSettingsProperties() {
121
- this._haveToolSettings = true;
122
- const toolSettings = new Array();
123
- toolSettings.push(this.latitudeProperty.toDialogItem({ rowPriority: 1, columnIndex: 2 }));
124
- toolSettings.push(this.longitudeProperty.toDialogItem({ rowPriority: 2, columnIndex: 2 }));
125
- toolSettings.push(this.altitudeProperty.toDialogItem({ rowPriority: 3, columnIndex: 2 }));
126
- toolSettings.push(this.northProperty.toDialogItem({ rowPriority: 4, columnIndex: 2 }));
127
- return toolSettings;
128
- }
129
- provideToolAssistance() {
130
- const acceptMsg = core_frontend_1.CoreTools.translate(undefined === this._origin ? "ElementSet.Inputs.AcceptPoint" : "ElementSet.Inputs.Accept");
131
- const rejectMsg = core_frontend_1.CoreTools.translate("ElementSet.Inputs.Cancel");
132
- const mainInstruction = core_frontend_1.ToolAssistance.createInstruction(this.iconSpec, translatePrompt(undefined === this._origin ? "IdentifyKnownLocation" : "ConfirmCoordinates"));
133
- const sections = [];
134
- const mouseInstructions = [];
135
- mouseInstructions.push(core_frontend_1.ToolAssistance.createInstruction(core_frontend_1.ToolAssistanceImage.LeftClick, acceptMsg, false, core_frontend_1.ToolAssistanceInputMethod.Mouse));
136
- mouseInstructions.push(core_frontend_1.ToolAssistance.createInstruction(core_frontend_1.ToolAssistanceImage.RightClick, rejectMsg, false, core_frontend_1.ToolAssistanceInputMethod.Mouse));
137
- sections.push(core_frontend_1.ToolAssistance.createSection(mouseInstructions, core_frontend_1.ToolAssistance.inputsLabel));
138
- const touchInstructions = [];
139
- if (!core_frontend_1.ToolAssistance.createTouchCursorInstructions(touchInstructions))
140
- touchInstructions.push(core_frontend_1.ToolAssistance.createInstruction(core_frontend_1.ToolAssistanceImage.OneTouchTap, acceptMsg, false, core_frontend_1.ToolAssistanceInputMethod.Touch));
141
- touchInstructions.push(core_frontend_1.ToolAssistance.createInstruction(core_frontend_1.ToolAssistanceImage.TwoTouchTap, rejectMsg, false, core_frontend_1.ToolAssistanceInputMethod.Touch));
142
- sections.push(core_frontend_1.ToolAssistance.createSection(touchInstructions, core_frontend_1.ToolAssistance.inputsLabel));
143
- const instructions = core_frontend_1.ToolAssistance.createInstructions(mainInstruction, sections);
144
- core_frontend_1.IModelApp.notifications.setToolAssistance(instructions);
145
- }
146
- setupAndPromptForNextAction() {
147
- core_frontend_1.IModelApp.accuSnap.enableSnap(undefined === this._origin);
148
- this.provideToolAssistance();
149
- }
150
- pulseDecoration() {
151
- if (!this._accept)
152
- return;
153
- const deco = ProjectExtentsDecoration_1.ProjectExtentsClipDecoration.get();
154
- if (undefined === deco)
155
- return;
156
- this._scale += 0.1;
157
- if (this._scale > 1.6)
158
- this._scale = 1.0;
159
- deco.viewport.invalidateDecorations();
160
- setTimeout(() => this.pulseDecoration(), 100);
161
- }
162
- unsuspendDecorations() {
163
- const deco = ProjectExtentsDecoration_1.ProjectExtentsClipDecoration.get();
164
- if (undefined !== deco)
165
- deco.suspendGeolocationDecorations = false;
166
- }
167
- decorate(context) {
168
- if (undefined === this._origin || !context.viewport.view.isSpatialView())
169
- return;
170
- const deco = ProjectExtentsDecoration_1.ProjectExtentsClipDecoration.get();
171
- if (undefined === deco)
172
- return;
173
- deco.suspendGeolocationDecorations = true;
174
- deco.drawMonumentPoint(context, this._origin, this._scale);
175
- if (undefined !== this._labelDeco)
176
- this._labelDeco.addDecoration(context);
177
- }
178
- async onMouseMotion(ev) {
179
- if (undefined === ev.viewport || this._accept)
180
- return;
181
- this._origin = ev.point.clone();
182
- ev.viewport.invalidateDecorations();
183
- }
184
- async onResetButtonUp(_ev) {
185
- await this.onReinitialize(); // Calls onRestartTool to exit...
186
- return core_frontend_1.EventHandled.No;
187
- }
188
- acceptDefaultLocation() {
189
- // Greenwich is better default when testing control handle w/o tool settings support...
190
- this.latitude = core_geometry_1.Angle.createDegrees(51.4934).radians;
191
- this.longitude = core_geometry_1.Angle.createDegrees(0.0098).radians;
192
- this.altitude = 50.0;
193
- this.north = 0.0;
194
- }
195
- acceptKnownLocation(ev) {
196
- const deco = ProjectExtentsDecoration_1.ProjectExtentsClipDecoration.get();
197
- if (undefined === deco)
198
- return;
199
- this._accept = true; // Require explicit accept to give user a chance to change values...
200
- this._origin = ev.point.clone();
201
- this._labelDeco = new LabelDecoration(this._origin, translatePrompt("SpecifyCoordinates"));
202
- if (!this._cartographicFromArgs) {
203
- if (this.iModel.isGeoLocated) {
204
- const cartographic = this.iModel.spatialToCartographicFromEcef(this._origin);
205
- this.latitude = cartographic.latitude;
206
- this.longitude = cartographic.longitude;
207
- this.altitude = cartographic.height;
208
- this.north = deco.getClockwiseAngleToNorth().radians;
209
- }
210
- else if (!this._haveToolSettings) {
211
- this.acceptDefaultLocation();
212
- }
213
- }
214
- this.syncToolSettingsCoordinates();
215
- this.pulseDecoration(); // Pulse to indicate that we are waiting for user input...
216
- this.setupAndPromptForNextAction();
217
- }
218
- async acceptCoordinates() {
219
- const deco = ProjectExtentsDecoration_1.ProjectExtentsClipDecoration.get();
220
- if (undefined === deco)
221
- return;
222
- const origin = core_common_1.Cartographic.fromRadians({ longitude: this.longitude, latitude: this.latitude, height: this.altitude });
223
- if (!deco.updateEcefLocation(origin, this._origin, core_geometry_1.Angle.createRadians(this.north)))
224
- return;
225
- return this.onReinitialize(); // Calls onRestartTool to exit...
226
- }
227
- async onDataButtonDown(ev) {
228
- if (undefined === ev.viewport)
229
- return core_frontend_1.EventHandled.No; // Shouldn't really happen...
230
- const haveKnownLocation = this._accept;
231
- if (!haveKnownLocation)
232
- this.acceptKnownLocation(ev);
233
- const needAcceptPoint = !haveKnownLocation && this._haveToolSettings;
234
- if (!needAcceptPoint)
235
- await this.acceptCoordinates();
236
- return core_frontend_1.EventHandled.No;
237
- }
238
- async onInstall() {
239
- if (!ProjectExtentsDecoration_1.ProjectExtentsClipDecoration.allowEcefLocationChange(false))
240
- return false;
241
- // Setup initial values here instead of supplyToolSettingsProperties to support keyin args w/o appui-react...
242
- this.initializeToolSettingPropertyValues([this.latitudeProperty, this.longitudeProperty, this.altitudeProperty, this.northProperty]);
243
- return true;
244
- }
245
- /** The keyin takes the following arguments, all of which are optional:
246
- * - `latitude=number` Latitude of accept point in degrees.
247
- * - `longitude=number` Longitude of accept point in degrees.
248
- * - `altitude=number` Height above ellipsoid of accept point.
249
- * - `north=number` North direction in degrees of accept point.
250
- */
251
- async parseAndRun(...inputArgs) {
252
- for (const arg of inputArgs) {
253
- const parts = arg.split("=");
254
- if (2 !== parts.length)
255
- continue;
256
- if (parts[0].toLowerCase().startsWith("la")) {
257
- const latitude = Number.parseFloat(parts[1]);
258
- if (!Number.isNaN(latitude)) {
259
- this.saveToolSettingPropertyValue(this.latitudeProperty, { value: core_geometry_1.Angle.createDegrees(latitude).radians });
260
- this._cartographicFromArgs = true;
261
- }
262
- }
263
- else if (parts[0].toLowerCase().startsWith("lo")) {
264
- const longitude = Number.parseFloat(parts[1]);
265
- if (!Number.isNaN(longitude)) {
266
- this.saveToolSettingPropertyValue(this.longitudeProperty, { value: core_geometry_1.Angle.createDegrees(longitude).radians });
267
- this._cartographicFromArgs = true;
268
- }
269
- }
270
- else if (parts[0].toLowerCase().startsWith("al")) {
271
- const altitude = Number.parseFloat(parts[1]);
272
- if (!Number.isNaN(altitude)) {
273
- this.saveToolSettingPropertyValue(this.altitudeProperty, { value: altitude });
274
- this._cartographicFromArgs = true;
275
- }
276
- }
277
- else if (parts[0].toLowerCase().startsWith("no")) {
278
- const north = Number.parseFloat(parts[1]);
279
- if (!Number.isNaN(north)) {
280
- this.saveToolSettingPropertyValue(this.northProperty, { value: core_geometry_1.Angle.createDegrees(north).radians });
281
- this._cartographicFromArgs = true;
282
- }
283
- }
284
- }
285
- return this.run();
286
- }
287
- static async startTool() { return new ProjectGeolocationPointTool().run(); }
288
- }
289
- exports.ProjectGeolocationPointTool = ProjectGeolocationPointTool;
290
- ProjectGeolocationPointTool.toolId = "ProjectLocation.Geolocation.Point";
291
- ProjectGeolocationPointTool.iconSpec = "icon-globe"; // <== Tool button should use whatever icon you have here...
292
- /** Change or update geolocation direction to true north.
293
- * @beta
294
- */
295
- class ProjectGeolocationNorthTool extends core_frontend_1.PrimitiveTool {
296
- isCompatibleViewport(vp, isSelectedViewChange) { return (super.isCompatibleViewport(vp, isSelectedViewChange) && undefined !== vp && vp.view.isSpatialView()); }
297
- isValidLocation(_ev, _isButtonEvent) { return true; } // Allow snapping to terrain, etc. outside project extents...
298
- requireWriteableTarget() { return false; } // Tool doesn't modify the imodel...
299
- async onPostInstall() {
300
- await super.onPostInstall();
301
- this.setupAndPromptForNextAction();
302
- }
303
- async onCleanup() {
304
- await super.onCleanup();
305
- this.unsuspendDecorations();
306
- }
307
- async onRestartTool() { return this.exitTool(); }
308
- async onUnsuspend() { this.provideToolAssistance(); }
309
- provideToolAssistance() {
310
- const acceptMsg = core_frontend_1.CoreTools.translate("ElementSet.Inputs.AcceptPoint");
311
- const rejectMsg = core_frontend_1.CoreTools.translate("ElementSet.Inputs.Cancel");
312
- const mainInstruction = core_frontend_1.ToolAssistance.createInstruction(this.iconSpec, translatePrompt(undefined === this._origin ? "IdentifyRefPoint" : "DefineAngle"));
313
- const sections = [];
314
- const mouseInstructions = [];
315
- mouseInstructions.push(core_frontend_1.ToolAssistance.createInstruction(core_frontend_1.ToolAssistanceImage.LeftClick, acceptMsg, false, core_frontend_1.ToolAssistanceInputMethod.Mouse));
316
- mouseInstructions.push(core_frontend_1.ToolAssistance.createInstruction(core_frontend_1.ToolAssistanceImage.RightClick, rejectMsg, false, core_frontend_1.ToolAssistanceInputMethod.Mouse));
317
- sections.push(core_frontend_1.ToolAssistance.createSection(mouseInstructions, core_frontend_1.ToolAssistance.inputsLabel));
318
- const touchInstructions = [];
319
- if (!core_frontend_1.ToolAssistance.createTouchCursorInstructions(touchInstructions))
320
- touchInstructions.push(core_frontend_1.ToolAssistance.createInstruction(core_frontend_1.ToolAssistanceImage.OneTouchTap, acceptMsg, false, core_frontend_1.ToolAssistanceInputMethod.Touch));
321
- touchInstructions.push(core_frontend_1.ToolAssistance.createInstruction(core_frontend_1.ToolAssistanceImage.TwoTouchTap, rejectMsg, false, core_frontend_1.ToolAssistanceInputMethod.Touch));
322
- sections.push(core_frontend_1.ToolAssistance.createSection(touchInstructions, core_frontend_1.ToolAssistance.inputsLabel));
323
- const instructions = core_frontend_1.ToolAssistance.createInstructions(mainInstruction, sections);
324
- core_frontend_1.IModelApp.notifications.setToolAssistance(instructions);
325
- }
326
- setupAndPromptForNextAction() {
327
- core_frontend_1.IModelApp.accuSnap.enableSnap(true);
328
- this.provideToolAssistance();
329
- if (undefined === this._origin)
330
- return;
331
- const hints = new core_frontend_1.AccuDrawHintBuilder();
332
- hints.setRotation(core_geometry_1.Matrix3d.createIdentity());
333
- hints.setOrigin(this._origin);
334
- hints.setModePolar();
335
- hints.setOriginFixed = true;
336
- hints.setLockZ = true;
337
- hints.sendHints();
338
- }
339
- getAdjustedPoint(ev) {
340
- if (undefined === this._origin)
341
- return undefined;
342
- return core_frontend_1.AccuDrawHintBuilder.projectPointToPlaneInView(ev.point, this._origin, core_geometry_1.Vector3d.unitZ(), ev.viewport, true);
343
- }
344
- unsuspendDecorations() {
345
- const deco = ProjectExtentsDecoration_1.ProjectExtentsClipDecoration.get();
346
- if (undefined !== deco)
347
- deco.suspendGeolocationDecorations = false;
348
- }
349
- updateNorthVector(ev) {
350
- if (undefined === ev.viewport)
351
- return;
352
- if (undefined === this._northDir)
353
- this._northDir = core_geometry_1.Ray3d.create(ev.point, core_geometry_1.Vector3d.unitY());
354
- else
355
- this._northDir.origin.setFrom(undefined !== this._origin ? this._origin : ev.point);
356
- const dirPt = this.getAdjustedPoint(ev);
357
- if (undefined === dirPt)
358
- return;
359
- this._northDir.direction.setStartEnd(this._northDir.origin, dirPt);
360
- if (this._northDir.direction.magnitude() < 1.0e-6)
361
- this._northDir.direction.setFrom(core_geometry_1.Vector3d.unitY());
362
- this._northDir.direction.z = 0.0;
363
- this._northDir.direction.normalizeInPlace();
364
- }
365
- decorate(context) {
366
- if (undefined === this._northDir || !context.viewport.view.isSpatialView())
367
- return;
368
- const deco = ProjectExtentsDecoration_1.ProjectExtentsClipDecoration.get();
369
- if (undefined === deco)
370
- return;
371
- deco.suspendGeolocationDecorations = true;
372
- deco.drawNorthArrow(context, this._northDir);
373
- }
374
- async onKeyTransition(wentDown, keyEvent) {
375
- if (core_frontend_1.EventHandled.Yes === await super.onKeyTransition(wentDown, keyEvent))
376
- return core_frontend_1.EventHandled.Yes;
377
- return (wentDown && await core_frontend_1.AccuDrawShortcuts.processShortcutKey(keyEvent)) ? core_frontend_1.EventHandled.Yes : core_frontend_1.EventHandled.No;
378
- }
379
- async onMouseMotion(ev) {
380
- if (undefined === ev.viewport)
381
- return;
382
- this.updateNorthVector(ev);
383
- ev.viewport.invalidateDecorations();
384
- }
385
- async onResetButtonUp(_ev) {
386
- await this.onReinitialize(); // Calls onRestartTool to exit...
387
- return core_frontend_1.EventHandled.No;
388
- }
389
- async onDataButtonDown(ev) {
390
- if (undefined === ev.viewport)
391
- return core_frontend_1.EventHandled.No; // Shouldn't really happen...
392
- if (undefined === this._origin) {
393
- this._origin = ev.point.clone();
394
- this.setupAndPromptForNextAction();
395
- return core_frontend_1.EventHandled.No;
396
- }
397
- this.updateNorthVector(ev);
398
- if (undefined !== this._northDir) {
399
- const deco = ProjectExtentsDecoration_1.ProjectExtentsClipDecoration.get();
400
- if (undefined !== deco)
401
- deco.updateNorthDirection(this._northDir);
402
- }
403
- await this.onReinitialize(); // Calls onRestartTool to exit...
404
- return core_frontend_1.EventHandled.No;
405
- }
406
- async onInstall() { return ProjectExtentsDecoration_1.ProjectExtentsClipDecoration.allowEcefLocationChange(true); }
407
- static async startTool() { return new ProjectGeolocationNorthTool().run(); }
408
- }
409
- exports.ProjectGeolocationNorthTool = ProjectGeolocationNorthTool;
410
- ProjectGeolocationNorthTool.toolId = "ProjectLocation.Geolocation.North";
411
- ProjectGeolocationNorthTool.iconSpec = "icon-sort-up"; // <== Tool button should use whatever icon you have here...
412
- /** Move a geolocated model by specifying two points to define the offset.
413
- * @beta
414
- */
415
- class ProjectGeolocationMoveTool extends core_frontend_1.PrimitiveTool {
416
- isCompatibleViewport(vp, isSelectedViewChange) { return (super.isCompatibleViewport(vp, isSelectedViewChange) && undefined !== vp && vp.view.isSpatialView()); }
417
- isValidLocation(_ev, _isButtonEvent) { return true; } // Allow snapping to terrain, etc. outside project extents...
418
- requireWriteableTarget() { return false; } // Tool doesn't modify the imodel...
419
- async onPostInstall() {
420
- await super.onPostInstall();
421
- this.setupAndPromptForNextAction();
422
- }
423
- async onCleanup() {
424
- await super.onCleanup();
425
- this.unsuspendDecorations();
426
- }
427
- async onRestartTool() {
428
- const tool = new ProjectGeolocationMoveTool();
429
- if (!await tool.run())
430
- return this.exitTool();
431
- }
432
- async onUnsuspend() { this.provideToolAssistance(); }
433
- provideToolAssistance() {
434
- const acceptMsg = core_frontend_1.CoreTools.translate("ElementSet.Inputs.AcceptPoint");
435
- const rejectMsg = core_frontend_1.CoreTools.translate("ElementSet.Inputs.Cancel");
436
- const mainInstruction = core_frontend_1.ToolAssistance.createInstruction(this.iconSpec, translatePrompt(undefined === this._origin ? "IdentifyRefPoint" : "DefineOffset"));
437
- const sections = [];
438
- const mouseInstructions = [];
439
- mouseInstructions.push(core_frontend_1.ToolAssistance.createInstruction(core_frontend_1.ToolAssistanceImage.LeftClick, acceptMsg, false, core_frontend_1.ToolAssistanceInputMethod.Mouse));
440
- mouseInstructions.push(core_frontend_1.ToolAssistance.createInstruction(core_frontend_1.ToolAssistanceImage.RightClick, rejectMsg, false, core_frontend_1.ToolAssistanceInputMethod.Mouse));
441
- sections.push(core_frontend_1.ToolAssistance.createSection(mouseInstructions, core_frontend_1.ToolAssistance.inputsLabel));
442
- const touchInstructions = [];
443
- if (!core_frontend_1.ToolAssistance.createTouchCursorInstructions(touchInstructions))
444
- touchInstructions.push(core_frontend_1.ToolAssistance.createInstruction(core_frontend_1.ToolAssistanceImage.OneTouchTap, acceptMsg, false, core_frontend_1.ToolAssistanceInputMethod.Touch));
445
- touchInstructions.push(core_frontend_1.ToolAssistance.createInstruction(core_frontend_1.ToolAssistanceImage.TwoTouchTap, rejectMsg, false, core_frontend_1.ToolAssistanceInputMethod.Touch));
446
- sections.push(core_frontend_1.ToolAssistance.createSection(touchInstructions, core_frontend_1.ToolAssistance.inputsLabel));
447
- const instructions = core_frontend_1.ToolAssistance.createInstructions(mainInstruction, sections);
448
- core_frontend_1.IModelApp.notifications.setToolAssistance(instructions);
449
- }
450
- setupAndPromptForNextAction() {
451
- core_frontend_1.IModelApp.accuSnap.enableSnap(true);
452
- this.provideToolAssistance();
453
- if (undefined === this._origin)
454
- return;
455
- const hints = new core_frontend_1.AccuDrawHintBuilder();
456
- hints.setRotation(core_geometry_1.Matrix3d.createIdentity());
457
- hints.setOrigin(this._origin);
458
- hints.setModePolar();
459
- hints.setOriginFixed = true;
460
- hints.sendHints();
461
- }
462
- unsuspendDecorations() {
463
- const deco = ProjectExtentsDecoration_1.ProjectExtentsClipDecoration.get();
464
- if (undefined !== deco)
465
- deco.suspendGeolocationDecorations = false;
466
- }
467
- async acceptOffset(ev) {
468
- if (undefined === ev.viewport || undefined === this._origin)
469
- return;
470
- const deco = ProjectExtentsDecoration_1.ProjectExtentsClipDecoration.get();
471
- if (undefined === deco)
472
- return;
473
- const origin = this.iModel.spatialToCartographicFromEcef(ev.point);
474
- if (!deco.updateEcefLocation(origin, this._origin))
475
- return;
476
- return this.onReinitialize(); // Calls onRestartTool to exit...
477
- }
478
- decorate(context) {
479
- if (undefined === this._origin || undefined === this._current || !context.viewport.view.isSpatialView())
480
- return;
481
- const deco = ProjectExtentsDecoration_1.ProjectExtentsClipDecoration.get();
482
- if (undefined === deco)
483
- return;
484
- const builderAccVis = context.createGraphicBuilder(core_frontend_1.GraphicType.WorldDecoration);
485
- const builderAccHid = context.createGraphicBuilder(core_frontend_1.GraphicType.WorldOverlay);
486
- const colorAccVis = core_common_1.ColorDef.white.adjustedForContrast(context.viewport.view.backgroundColor);
487
- const colorAccHid = colorAccVis.withAlpha(100);
488
- builderAccVis.setSymbology(colorAccVis, core_common_1.ColorDef.black, 3);
489
- builderAccHid.setSymbology(colorAccHid, core_common_1.ColorDef.black, 1, core_common_1.LinePixels.Code2);
490
- const extents = this.iModel.projectExtents.cloneTranslated(core_geometry_1.Vector3d.createStartEnd(this._origin, this._current));
491
- builderAccVis.addRangeBox(extents);
492
- builderAccHid.addRangeBox(extents);
493
- builderAccHid.addLineString([this._origin, this._current]);
494
- context.addDecorationFromBuilder(builderAccVis);
495
- context.addDecorationFromBuilder(builderAccHid);
496
- deco.suspendGeolocationDecorations = true;
497
- }
498
- async onKeyTransition(wentDown, keyEvent) {
499
- if (core_frontend_1.EventHandled.Yes === await super.onKeyTransition(wentDown, keyEvent))
500
- return core_frontend_1.EventHandled.Yes;
501
- return (wentDown && await core_frontend_1.AccuDrawShortcuts.processShortcutKey(keyEvent)) ? core_frontend_1.EventHandled.Yes : core_frontend_1.EventHandled.No;
502
- }
503
- async onMouseMotion(ev) {
504
- if (undefined === ev.viewport)
505
- return;
506
- this._current = ev.point;
507
- ev.viewport.invalidateDecorations();
508
- }
509
- async onResetButtonUp(_ev) {
510
- if (undefined === this._origin)
511
- await this.exitTool(); // exit to select tool if we haven't gotten first point...
512
- else
513
- await this.onReinitialize(); // Calls onRestartTool...
514
- return core_frontend_1.EventHandled.No;
515
- }
516
- async onDataButtonDown(ev) {
517
- if (undefined === ev.viewport)
518
- return core_frontend_1.EventHandled.No; // Shouldn't really happen...
519
- if (undefined === this._origin) {
520
- this._origin = ev.point.clone();
521
- this.setupAndPromptForNextAction();
522
- return core_frontend_1.EventHandled.No;
523
- }
524
- await this.acceptOffset(ev);
525
- return core_frontend_1.EventHandled.No;
526
- }
527
- async onInstall() { return ProjectExtentsDecoration_1.ProjectExtentsClipDecoration.allowEcefLocationChange(true); }
528
- static async startTool() { return new ProjectGeolocationMoveTool().run(); }
529
- }
530
- exports.ProjectGeolocationMoveTool = ProjectGeolocationMoveTool;
531
- ProjectGeolocationMoveTool.toolId = "ProjectLocation.Geolocation.Move";
532
- ProjectGeolocationMoveTool.iconSpec = "icon-move"; // <== Tool button should use whatever icon you have here...
1
+ "use strict";
2
+ /*---------------------------------------------------------------------------------------------
3
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
4
+ * See LICENSE.md in the project root for license terms and full copyright notice.
5
+ *--------------------------------------------------------------------------------------------*/
6
+ /** @packageDocumentation
7
+ * @module Editing
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.ProjectGeolocationMoveTool = exports.ProjectGeolocationNorthTool = exports.ProjectGeolocationPointTool = void 0;
11
+ const core_frontend_1 = require("@itwin/core-frontend");
12
+ const core_geometry_1 = require("@itwin/core-geometry");
13
+ const core_common_1 = require("@itwin/core-common");
14
+ const ProjectExtentsDecoration_1 = require("./ProjectExtentsDecoration");
15
+ const appui_abstract_1 = require("@itwin/appui-abstract");
16
+ const EditTool_1 = require("../EditTool");
17
+ function translatePrompt(key) {
18
+ return EditTool_1.EditTools.translate(`ProjectLocation:Prompts.${key}`);
19
+ }
20
+ function translateMessage(key) {
21
+ return EditTool_1.EditTools.translate(`ProjectLocation:Message.${key}`);
22
+ }
23
+ /** @internal */
24
+ class LabelDecoration {
25
+ constructor(worldLocation, label) {
26
+ this.worldLocation = new core_geometry_1.Point3d();
27
+ this.position = new core_geometry_1.Point3d();
28
+ this.worldLocation.setFrom(worldLocation);
29
+ this.label = label;
30
+ }
31
+ drawDecoration(ctx) {
32
+ ctx.font = "16px san-serif";
33
+ const labelHeight = ctx.measureText("M").width; // Close enough for border padding...
34
+ const labelWidth = ctx.measureText(this.label).width + labelHeight;
35
+ ctx.lineWidth = 1;
36
+ ctx.strokeStyle = "white";
37
+ ctx.fillStyle = "rgba(0,0,0,.4)";
38
+ ctx.shadowColor = "black";
39
+ ctx.shadowBlur = 10;
40
+ ctx.fillRect(-(labelWidth / 2), -labelHeight, labelWidth, labelHeight * 2);
41
+ ctx.strokeRect(-(labelWidth / 2), -labelHeight, labelWidth, labelHeight * 2);
42
+ ctx.fillStyle = "white";
43
+ ctx.shadowBlur = 0;
44
+ ctx.textAlign = "center";
45
+ ctx.textBaseline = "middle";
46
+ ctx.fillText(this.label, 0, 0);
47
+ }
48
+ setPosition(vp) {
49
+ vp.worldToView(this.worldLocation, this.position);
50
+ this.position.y -= Math.floor(vp.pixelsFromInches(0.45)) + 0.5; // Offset from world location...
51
+ return vp.viewRect.containsPoint(this.position);
52
+ }
53
+ addDecoration(context) {
54
+ if (this.setPosition(context.viewport))
55
+ context.addCanvasDecoration(this);
56
+ }
57
+ }
58
+ /** Change or update geolocation for project.
59
+ * To show tool settings for specifying lat/long, make sure formatting and parsing data are cached before the tool starts
60
+ * by calling QuantityFormatter.onInitialized at app startup.
61
+ * @beta
62
+ */
63
+ class ProjectGeolocationPointTool extends core_frontend_1.PrimitiveTool {
64
+ constructor() {
65
+ super(...arguments);
66
+ this._haveToolSettings = false;
67
+ this._cartographicFromArgs = false;
68
+ this._accept = false;
69
+ this._scale = 1.0;
70
+ }
71
+ static get minArgs() { return 0; }
72
+ static get maxArgs() { return 4; } // latitude, longitude, altitude, north direction...
73
+ isCompatibleViewport(vp, isSelectedViewChange) { return (super.isCompatibleViewport(vp, isSelectedViewChange) && undefined !== vp && vp.view.isSpatialView()); }
74
+ isValidLocation(_ev, _isButtonEvent) { return true; } // Allow snapping to terrain, etc. outside project extents...
75
+ requireWriteableTarget() { return false; } // Tool doesn't modify the imodel...
76
+ async onPostInstall() {
77
+ await super.onPostInstall();
78
+ this.setupAndPromptForNextAction();
79
+ }
80
+ async onCleanup() {
81
+ await super.onCleanup();
82
+ this.unsuspendDecorations();
83
+ }
84
+ async onRestartTool() { return this.exitTool(); }
85
+ async onUnsuspend() { this.provideToolAssistance(); }
86
+ get latitudeProperty() {
87
+ if (!this._latitudeProperty)
88
+ this._latitudeProperty = new appui_abstract_1.DialogProperty(new core_frontend_1.AngleDescription("latitude", translateMessage("Latitude")), 0.0);
89
+ return this._latitudeProperty;
90
+ }
91
+ get latitude() { return this.latitudeProperty.value; }
92
+ set latitude(value) { this.latitudeProperty.value = value; }
93
+ get longitudeProperty() {
94
+ if (!this._longitudeProperty)
95
+ this._longitudeProperty = new appui_abstract_1.DialogProperty(new core_frontend_1.AngleDescription("longitude", translateMessage("Longitude")), 0.0);
96
+ return this._longitudeProperty;
97
+ }
98
+ get longitude() { return this.longitudeProperty.value; }
99
+ set longitude(value) { this.longitudeProperty.value = value; }
100
+ get altitudeProperty() {
101
+ if (!this._altitudeProperty)
102
+ this._altitudeProperty = new appui_abstract_1.DialogProperty(new core_frontend_1.LengthDescription("altitude", core_frontend_1.CoreTools.translate("Measure.Labels.Altitude")), 0.0);
103
+ return this._altitudeProperty;
104
+ }
105
+ get altitude() { return this.altitudeProperty.value; }
106
+ set altitude(value) { this.altitudeProperty.value = value; }
107
+ get northProperty() {
108
+ if (!this._northProperty)
109
+ this._northProperty = new appui_abstract_1.DialogProperty(new core_frontend_1.AngleDescription("north", translateMessage("North")), 0.0);
110
+ return this._northProperty;
111
+ }
112
+ get north() { return this.northProperty.value; }
113
+ set north(value) { this.northProperty.value = value; }
114
+ syncToolSettingsCoordinates() {
115
+ this.syncToolSettingsProperties([this.latitudeProperty.syncItem, this.longitudeProperty.syncItem, this.altitudeProperty.syncItem, this.northProperty.syncItem]);
116
+ }
117
+ async applyToolSettingPropertyChange(updatedValue) {
118
+ return this.changeToolSettingPropertyValue(updatedValue);
119
+ }
120
+ supplyToolSettingsProperties() {
121
+ this._haveToolSettings = true;
122
+ const toolSettings = new Array();
123
+ toolSettings.push(this.latitudeProperty.toDialogItem({ rowPriority: 1, columnIndex: 2 }));
124
+ toolSettings.push(this.longitudeProperty.toDialogItem({ rowPriority: 2, columnIndex: 2 }));
125
+ toolSettings.push(this.altitudeProperty.toDialogItem({ rowPriority: 3, columnIndex: 2 }));
126
+ toolSettings.push(this.northProperty.toDialogItem({ rowPriority: 4, columnIndex: 2 }));
127
+ return toolSettings;
128
+ }
129
+ provideToolAssistance() {
130
+ const acceptMsg = core_frontend_1.CoreTools.translate(undefined === this._origin ? "ElementSet.Inputs.AcceptPoint" : "ElementSet.Inputs.Accept");
131
+ const rejectMsg = core_frontend_1.CoreTools.translate("ElementSet.Inputs.Cancel");
132
+ const mainInstruction = core_frontend_1.ToolAssistance.createInstruction(this.iconSpec, translatePrompt(undefined === this._origin ? "IdentifyKnownLocation" : "ConfirmCoordinates"));
133
+ const sections = [];
134
+ const mouseInstructions = [];
135
+ mouseInstructions.push(core_frontend_1.ToolAssistance.createInstruction(core_frontend_1.ToolAssistanceImage.LeftClick, acceptMsg, false, core_frontend_1.ToolAssistanceInputMethod.Mouse));
136
+ mouseInstructions.push(core_frontend_1.ToolAssistance.createInstruction(core_frontend_1.ToolAssistanceImage.RightClick, rejectMsg, false, core_frontend_1.ToolAssistanceInputMethod.Mouse));
137
+ sections.push(core_frontend_1.ToolAssistance.createSection(mouseInstructions, core_frontend_1.ToolAssistance.inputsLabel));
138
+ const touchInstructions = [];
139
+ if (!core_frontend_1.ToolAssistance.createTouchCursorInstructions(touchInstructions))
140
+ touchInstructions.push(core_frontend_1.ToolAssistance.createInstruction(core_frontend_1.ToolAssistanceImage.OneTouchTap, acceptMsg, false, core_frontend_1.ToolAssistanceInputMethod.Touch));
141
+ touchInstructions.push(core_frontend_1.ToolAssistance.createInstruction(core_frontend_1.ToolAssistanceImage.TwoTouchTap, rejectMsg, false, core_frontend_1.ToolAssistanceInputMethod.Touch));
142
+ sections.push(core_frontend_1.ToolAssistance.createSection(touchInstructions, core_frontend_1.ToolAssistance.inputsLabel));
143
+ const instructions = core_frontend_1.ToolAssistance.createInstructions(mainInstruction, sections);
144
+ core_frontend_1.IModelApp.notifications.setToolAssistance(instructions);
145
+ }
146
+ setupAndPromptForNextAction() {
147
+ core_frontend_1.IModelApp.accuSnap.enableSnap(undefined === this._origin);
148
+ this.provideToolAssistance();
149
+ }
150
+ pulseDecoration() {
151
+ if (!this._accept)
152
+ return;
153
+ const deco = ProjectExtentsDecoration_1.ProjectExtentsClipDecoration.get();
154
+ if (undefined === deco)
155
+ return;
156
+ this._scale += 0.1;
157
+ if (this._scale > 1.6)
158
+ this._scale = 1.0;
159
+ deco.viewport.invalidateDecorations();
160
+ setTimeout(() => this.pulseDecoration(), 100);
161
+ }
162
+ unsuspendDecorations() {
163
+ const deco = ProjectExtentsDecoration_1.ProjectExtentsClipDecoration.get();
164
+ if (undefined !== deco)
165
+ deco.suspendGeolocationDecorations = false;
166
+ }
167
+ decorate(context) {
168
+ if (undefined === this._origin || !context.viewport.view.isSpatialView())
169
+ return;
170
+ const deco = ProjectExtentsDecoration_1.ProjectExtentsClipDecoration.get();
171
+ if (undefined === deco)
172
+ return;
173
+ deco.suspendGeolocationDecorations = true;
174
+ deco.drawMonumentPoint(context, this._origin, this._scale);
175
+ if (undefined !== this._labelDeco)
176
+ this._labelDeco.addDecoration(context);
177
+ }
178
+ async onMouseMotion(ev) {
179
+ if (undefined === ev.viewport || this._accept)
180
+ return;
181
+ this._origin = ev.point.clone();
182
+ ev.viewport.invalidateDecorations();
183
+ }
184
+ async onResetButtonUp(_ev) {
185
+ await this.onReinitialize(); // Calls onRestartTool to exit...
186
+ return core_frontend_1.EventHandled.No;
187
+ }
188
+ acceptDefaultLocation() {
189
+ // Greenwich is better default when testing control handle w/o tool settings support...
190
+ this.latitude = core_geometry_1.Angle.createDegrees(51.4934).radians;
191
+ this.longitude = core_geometry_1.Angle.createDegrees(0.0098).radians;
192
+ this.altitude = 50.0;
193
+ this.north = 0.0;
194
+ }
195
+ acceptKnownLocation(ev) {
196
+ const deco = ProjectExtentsDecoration_1.ProjectExtentsClipDecoration.get();
197
+ if (undefined === deco)
198
+ return;
199
+ this._accept = true; // Require explicit accept to give user a chance to change values...
200
+ this._origin = ev.point.clone();
201
+ this._labelDeco = new LabelDecoration(this._origin, translatePrompt("SpecifyCoordinates"));
202
+ if (!this._cartographicFromArgs) {
203
+ if (this.iModel.isGeoLocated) {
204
+ const cartographic = this.iModel.spatialToCartographicFromEcef(this._origin);
205
+ this.latitude = cartographic.latitude;
206
+ this.longitude = cartographic.longitude;
207
+ this.altitude = cartographic.height;
208
+ this.north = deco.getClockwiseAngleToNorth().radians;
209
+ }
210
+ else if (!this._haveToolSettings) {
211
+ this.acceptDefaultLocation();
212
+ }
213
+ }
214
+ this.syncToolSettingsCoordinates();
215
+ this.pulseDecoration(); // Pulse to indicate that we are waiting for user input...
216
+ this.setupAndPromptForNextAction();
217
+ }
218
+ async acceptCoordinates() {
219
+ const deco = ProjectExtentsDecoration_1.ProjectExtentsClipDecoration.get();
220
+ if (undefined === deco)
221
+ return;
222
+ const origin = core_common_1.Cartographic.fromRadians({ longitude: this.longitude, latitude: this.latitude, height: this.altitude });
223
+ if (!deco.updateEcefLocation(origin, this._origin, core_geometry_1.Angle.createRadians(this.north)))
224
+ return;
225
+ return this.onReinitialize(); // Calls onRestartTool to exit...
226
+ }
227
+ async onDataButtonDown(ev) {
228
+ if (undefined === ev.viewport)
229
+ return core_frontend_1.EventHandled.No; // Shouldn't really happen...
230
+ const haveKnownLocation = this._accept;
231
+ if (!haveKnownLocation)
232
+ this.acceptKnownLocation(ev);
233
+ const needAcceptPoint = !haveKnownLocation && this._haveToolSettings;
234
+ if (!needAcceptPoint)
235
+ await this.acceptCoordinates();
236
+ return core_frontend_1.EventHandled.No;
237
+ }
238
+ async onInstall() {
239
+ if (!ProjectExtentsDecoration_1.ProjectExtentsClipDecoration.allowEcefLocationChange(false))
240
+ return false;
241
+ // Setup initial values here instead of supplyToolSettingsProperties to support keyin args w/o appui-react...
242
+ this.initializeToolSettingPropertyValues([this.latitudeProperty, this.longitudeProperty, this.altitudeProperty, this.northProperty]);
243
+ return true;
244
+ }
245
+ /** The keyin takes the following arguments, all of which are optional:
246
+ * - `latitude=number` Latitude of accept point in degrees.
247
+ * - `longitude=number` Longitude of accept point in degrees.
248
+ * - `altitude=number` Height above ellipsoid of accept point.
249
+ * - `north=number` North direction in degrees of accept point.
250
+ */
251
+ async parseAndRun(...inputArgs) {
252
+ for (const arg of inputArgs) {
253
+ const parts = arg.split("=");
254
+ if (2 !== parts.length)
255
+ continue;
256
+ if (parts[0].toLowerCase().startsWith("la")) {
257
+ const latitude = Number.parseFloat(parts[1]);
258
+ if (!Number.isNaN(latitude)) {
259
+ this.saveToolSettingPropertyValue(this.latitudeProperty, { value: core_geometry_1.Angle.createDegrees(latitude).radians });
260
+ this._cartographicFromArgs = true;
261
+ }
262
+ }
263
+ else if (parts[0].toLowerCase().startsWith("lo")) {
264
+ const longitude = Number.parseFloat(parts[1]);
265
+ if (!Number.isNaN(longitude)) {
266
+ this.saveToolSettingPropertyValue(this.longitudeProperty, { value: core_geometry_1.Angle.createDegrees(longitude).radians });
267
+ this._cartographicFromArgs = true;
268
+ }
269
+ }
270
+ else if (parts[0].toLowerCase().startsWith("al")) {
271
+ const altitude = Number.parseFloat(parts[1]);
272
+ if (!Number.isNaN(altitude)) {
273
+ this.saveToolSettingPropertyValue(this.altitudeProperty, { value: altitude });
274
+ this._cartographicFromArgs = true;
275
+ }
276
+ }
277
+ else if (parts[0].toLowerCase().startsWith("no")) {
278
+ const north = Number.parseFloat(parts[1]);
279
+ if (!Number.isNaN(north)) {
280
+ this.saveToolSettingPropertyValue(this.northProperty, { value: core_geometry_1.Angle.createDegrees(north).radians });
281
+ this._cartographicFromArgs = true;
282
+ }
283
+ }
284
+ }
285
+ return this.run();
286
+ }
287
+ static async startTool() { return new ProjectGeolocationPointTool().run(); }
288
+ }
289
+ exports.ProjectGeolocationPointTool = ProjectGeolocationPointTool;
290
+ ProjectGeolocationPointTool.toolId = "ProjectLocation.Geolocation.Point";
291
+ ProjectGeolocationPointTool.iconSpec = "icon-globe"; // <== Tool button should use whatever icon you have here...
292
+ /** Change or update geolocation direction to true north.
293
+ * @beta
294
+ */
295
+ class ProjectGeolocationNorthTool extends core_frontend_1.PrimitiveTool {
296
+ isCompatibleViewport(vp, isSelectedViewChange) { return (super.isCompatibleViewport(vp, isSelectedViewChange) && undefined !== vp && vp.view.isSpatialView()); }
297
+ isValidLocation(_ev, _isButtonEvent) { return true; } // Allow snapping to terrain, etc. outside project extents...
298
+ requireWriteableTarget() { return false; } // Tool doesn't modify the imodel...
299
+ async onPostInstall() {
300
+ await super.onPostInstall();
301
+ this.setupAndPromptForNextAction();
302
+ }
303
+ async onCleanup() {
304
+ await super.onCleanup();
305
+ this.unsuspendDecorations();
306
+ }
307
+ async onRestartTool() { return this.exitTool(); }
308
+ async onUnsuspend() { this.provideToolAssistance(); }
309
+ provideToolAssistance() {
310
+ const acceptMsg = core_frontend_1.CoreTools.translate("ElementSet.Inputs.AcceptPoint");
311
+ const rejectMsg = core_frontend_1.CoreTools.translate("ElementSet.Inputs.Cancel");
312
+ const mainInstruction = core_frontend_1.ToolAssistance.createInstruction(this.iconSpec, translatePrompt(undefined === this._origin ? "IdentifyRefPoint" : "DefineAngle"));
313
+ const sections = [];
314
+ const mouseInstructions = [];
315
+ mouseInstructions.push(core_frontend_1.ToolAssistance.createInstruction(core_frontend_1.ToolAssistanceImage.LeftClick, acceptMsg, false, core_frontend_1.ToolAssistanceInputMethod.Mouse));
316
+ mouseInstructions.push(core_frontend_1.ToolAssistance.createInstruction(core_frontend_1.ToolAssistanceImage.RightClick, rejectMsg, false, core_frontend_1.ToolAssistanceInputMethod.Mouse));
317
+ sections.push(core_frontend_1.ToolAssistance.createSection(mouseInstructions, core_frontend_1.ToolAssistance.inputsLabel));
318
+ const touchInstructions = [];
319
+ if (!core_frontend_1.ToolAssistance.createTouchCursorInstructions(touchInstructions))
320
+ touchInstructions.push(core_frontend_1.ToolAssistance.createInstruction(core_frontend_1.ToolAssistanceImage.OneTouchTap, acceptMsg, false, core_frontend_1.ToolAssistanceInputMethod.Touch));
321
+ touchInstructions.push(core_frontend_1.ToolAssistance.createInstruction(core_frontend_1.ToolAssistanceImage.TwoTouchTap, rejectMsg, false, core_frontend_1.ToolAssistanceInputMethod.Touch));
322
+ sections.push(core_frontend_1.ToolAssistance.createSection(touchInstructions, core_frontend_1.ToolAssistance.inputsLabel));
323
+ const instructions = core_frontend_1.ToolAssistance.createInstructions(mainInstruction, sections);
324
+ core_frontend_1.IModelApp.notifications.setToolAssistance(instructions);
325
+ }
326
+ setupAndPromptForNextAction() {
327
+ core_frontend_1.IModelApp.accuSnap.enableSnap(true);
328
+ this.provideToolAssistance();
329
+ if (undefined === this._origin)
330
+ return;
331
+ const hints = new core_frontend_1.AccuDrawHintBuilder();
332
+ hints.setRotation(core_geometry_1.Matrix3d.createIdentity());
333
+ hints.setOrigin(this._origin);
334
+ hints.setModePolar();
335
+ hints.setOriginFixed = true;
336
+ hints.setLockZ = true;
337
+ hints.sendHints();
338
+ }
339
+ getAdjustedPoint(ev) {
340
+ if (undefined === this._origin)
341
+ return undefined;
342
+ return core_frontend_1.AccuDrawHintBuilder.projectPointToPlaneInView(ev.point, this._origin, core_geometry_1.Vector3d.unitZ(), ev.viewport, true);
343
+ }
344
+ unsuspendDecorations() {
345
+ const deco = ProjectExtentsDecoration_1.ProjectExtentsClipDecoration.get();
346
+ if (undefined !== deco)
347
+ deco.suspendGeolocationDecorations = false;
348
+ }
349
+ updateNorthVector(ev) {
350
+ if (undefined === ev.viewport)
351
+ return;
352
+ if (undefined === this._northDir)
353
+ this._northDir = core_geometry_1.Ray3d.create(ev.point, core_geometry_1.Vector3d.unitY());
354
+ else
355
+ this._northDir.origin.setFrom(undefined !== this._origin ? this._origin : ev.point);
356
+ const dirPt = this.getAdjustedPoint(ev);
357
+ if (undefined === dirPt)
358
+ return;
359
+ this._northDir.direction.setStartEnd(this._northDir.origin, dirPt);
360
+ if (this._northDir.direction.magnitude() < 1.0e-6)
361
+ this._northDir.direction.setFrom(core_geometry_1.Vector3d.unitY());
362
+ this._northDir.direction.z = 0.0;
363
+ this._northDir.direction.normalizeInPlace();
364
+ }
365
+ decorate(context) {
366
+ if (undefined === this._northDir || !context.viewport.view.isSpatialView())
367
+ return;
368
+ const deco = ProjectExtentsDecoration_1.ProjectExtentsClipDecoration.get();
369
+ if (undefined === deco)
370
+ return;
371
+ deco.suspendGeolocationDecorations = true;
372
+ deco.drawNorthArrow(context, this._northDir);
373
+ }
374
+ async onKeyTransition(wentDown, keyEvent) {
375
+ if (core_frontend_1.EventHandled.Yes === await super.onKeyTransition(wentDown, keyEvent))
376
+ return core_frontend_1.EventHandled.Yes;
377
+ return (wentDown && await core_frontend_1.AccuDrawShortcuts.processShortcutKey(keyEvent)) ? core_frontend_1.EventHandled.Yes : core_frontend_1.EventHandled.No;
378
+ }
379
+ async onMouseMotion(ev) {
380
+ if (undefined === ev.viewport)
381
+ return;
382
+ this.updateNorthVector(ev);
383
+ ev.viewport.invalidateDecorations();
384
+ }
385
+ async onResetButtonUp(_ev) {
386
+ await this.onReinitialize(); // Calls onRestartTool to exit...
387
+ return core_frontend_1.EventHandled.No;
388
+ }
389
+ async onDataButtonDown(ev) {
390
+ if (undefined === ev.viewport)
391
+ return core_frontend_1.EventHandled.No; // Shouldn't really happen...
392
+ if (undefined === this._origin) {
393
+ this._origin = ev.point.clone();
394
+ this.setupAndPromptForNextAction();
395
+ return core_frontend_1.EventHandled.No;
396
+ }
397
+ this.updateNorthVector(ev);
398
+ if (undefined !== this._northDir) {
399
+ const deco = ProjectExtentsDecoration_1.ProjectExtentsClipDecoration.get();
400
+ if (undefined !== deco)
401
+ deco.updateNorthDirection(this._northDir);
402
+ }
403
+ await this.onReinitialize(); // Calls onRestartTool to exit...
404
+ return core_frontend_1.EventHandled.No;
405
+ }
406
+ async onInstall() { return ProjectExtentsDecoration_1.ProjectExtentsClipDecoration.allowEcefLocationChange(true); }
407
+ static async startTool() { return new ProjectGeolocationNorthTool().run(); }
408
+ }
409
+ exports.ProjectGeolocationNorthTool = ProjectGeolocationNorthTool;
410
+ ProjectGeolocationNorthTool.toolId = "ProjectLocation.Geolocation.North";
411
+ ProjectGeolocationNorthTool.iconSpec = "icon-sort-up"; // <== Tool button should use whatever icon you have here...
412
+ /** Move a geolocated model by specifying two points to define the offset.
413
+ * @beta
414
+ */
415
+ class ProjectGeolocationMoveTool extends core_frontend_1.PrimitiveTool {
416
+ isCompatibleViewport(vp, isSelectedViewChange) { return (super.isCompatibleViewport(vp, isSelectedViewChange) && undefined !== vp && vp.view.isSpatialView()); }
417
+ isValidLocation(_ev, _isButtonEvent) { return true; } // Allow snapping to terrain, etc. outside project extents...
418
+ requireWriteableTarget() { return false; } // Tool doesn't modify the imodel...
419
+ async onPostInstall() {
420
+ await super.onPostInstall();
421
+ this.setupAndPromptForNextAction();
422
+ }
423
+ async onCleanup() {
424
+ await super.onCleanup();
425
+ this.unsuspendDecorations();
426
+ }
427
+ async onRestartTool() {
428
+ const tool = new ProjectGeolocationMoveTool();
429
+ if (!await tool.run())
430
+ return this.exitTool();
431
+ }
432
+ async onUnsuspend() { this.provideToolAssistance(); }
433
+ provideToolAssistance() {
434
+ const acceptMsg = core_frontend_1.CoreTools.translate("ElementSet.Inputs.AcceptPoint");
435
+ const rejectMsg = core_frontend_1.CoreTools.translate("ElementSet.Inputs.Cancel");
436
+ const mainInstruction = core_frontend_1.ToolAssistance.createInstruction(this.iconSpec, translatePrompt(undefined === this._origin ? "IdentifyRefPoint" : "DefineOffset"));
437
+ const sections = [];
438
+ const mouseInstructions = [];
439
+ mouseInstructions.push(core_frontend_1.ToolAssistance.createInstruction(core_frontend_1.ToolAssistanceImage.LeftClick, acceptMsg, false, core_frontend_1.ToolAssistanceInputMethod.Mouse));
440
+ mouseInstructions.push(core_frontend_1.ToolAssistance.createInstruction(core_frontend_1.ToolAssistanceImage.RightClick, rejectMsg, false, core_frontend_1.ToolAssistanceInputMethod.Mouse));
441
+ sections.push(core_frontend_1.ToolAssistance.createSection(mouseInstructions, core_frontend_1.ToolAssistance.inputsLabel));
442
+ const touchInstructions = [];
443
+ if (!core_frontend_1.ToolAssistance.createTouchCursorInstructions(touchInstructions))
444
+ touchInstructions.push(core_frontend_1.ToolAssistance.createInstruction(core_frontend_1.ToolAssistanceImage.OneTouchTap, acceptMsg, false, core_frontend_1.ToolAssistanceInputMethod.Touch));
445
+ touchInstructions.push(core_frontend_1.ToolAssistance.createInstruction(core_frontend_1.ToolAssistanceImage.TwoTouchTap, rejectMsg, false, core_frontend_1.ToolAssistanceInputMethod.Touch));
446
+ sections.push(core_frontend_1.ToolAssistance.createSection(touchInstructions, core_frontend_1.ToolAssistance.inputsLabel));
447
+ const instructions = core_frontend_1.ToolAssistance.createInstructions(mainInstruction, sections);
448
+ core_frontend_1.IModelApp.notifications.setToolAssistance(instructions);
449
+ }
450
+ setupAndPromptForNextAction() {
451
+ core_frontend_1.IModelApp.accuSnap.enableSnap(true);
452
+ this.provideToolAssistance();
453
+ if (undefined === this._origin)
454
+ return;
455
+ const hints = new core_frontend_1.AccuDrawHintBuilder();
456
+ hints.setRotation(core_geometry_1.Matrix3d.createIdentity());
457
+ hints.setOrigin(this._origin);
458
+ hints.setModePolar();
459
+ hints.setOriginFixed = true;
460
+ hints.sendHints();
461
+ }
462
+ unsuspendDecorations() {
463
+ const deco = ProjectExtentsDecoration_1.ProjectExtentsClipDecoration.get();
464
+ if (undefined !== deco)
465
+ deco.suspendGeolocationDecorations = false;
466
+ }
467
+ async acceptOffset(ev) {
468
+ if (undefined === ev.viewport || undefined === this._origin)
469
+ return;
470
+ const deco = ProjectExtentsDecoration_1.ProjectExtentsClipDecoration.get();
471
+ if (undefined === deco)
472
+ return;
473
+ const origin = this.iModel.spatialToCartographicFromEcef(ev.point);
474
+ if (!deco.updateEcefLocation(origin, this._origin))
475
+ return;
476
+ return this.onReinitialize(); // Calls onRestartTool to exit...
477
+ }
478
+ decorate(context) {
479
+ if (undefined === this._origin || undefined === this._current || !context.viewport.view.isSpatialView())
480
+ return;
481
+ const deco = ProjectExtentsDecoration_1.ProjectExtentsClipDecoration.get();
482
+ if (undefined === deco)
483
+ return;
484
+ const builderAccVis = context.createGraphicBuilder(core_frontend_1.GraphicType.WorldDecoration);
485
+ const builderAccHid = context.createGraphicBuilder(core_frontend_1.GraphicType.WorldOverlay);
486
+ const colorAccVis = core_common_1.ColorDef.white.adjustedForContrast(context.viewport.view.backgroundColor);
487
+ const colorAccHid = colorAccVis.withAlpha(100);
488
+ builderAccVis.setSymbology(colorAccVis, core_common_1.ColorDef.black, 3);
489
+ builderAccHid.setSymbology(colorAccHid, core_common_1.ColorDef.black, 1, core_common_1.LinePixels.Code2);
490
+ const extents = this.iModel.projectExtents.cloneTranslated(core_geometry_1.Vector3d.createStartEnd(this._origin, this._current));
491
+ builderAccVis.addRangeBox(extents);
492
+ builderAccHid.addRangeBox(extents);
493
+ builderAccHid.addLineString([this._origin, this._current]);
494
+ context.addDecorationFromBuilder(builderAccVis);
495
+ context.addDecorationFromBuilder(builderAccHid);
496
+ deco.suspendGeolocationDecorations = true;
497
+ }
498
+ async onKeyTransition(wentDown, keyEvent) {
499
+ if (core_frontend_1.EventHandled.Yes === await super.onKeyTransition(wentDown, keyEvent))
500
+ return core_frontend_1.EventHandled.Yes;
501
+ return (wentDown && await core_frontend_1.AccuDrawShortcuts.processShortcutKey(keyEvent)) ? core_frontend_1.EventHandled.Yes : core_frontend_1.EventHandled.No;
502
+ }
503
+ async onMouseMotion(ev) {
504
+ if (undefined === ev.viewport)
505
+ return;
506
+ this._current = ev.point;
507
+ ev.viewport.invalidateDecorations();
508
+ }
509
+ async onResetButtonUp(_ev) {
510
+ if (undefined === this._origin)
511
+ await this.exitTool(); // exit to select tool if we haven't gotten first point...
512
+ else
513
+ await this.onReinitialize(); // Calls onRestartTool...
514
+ return core_frontend_1.EventHandled.No;
515
+ }
516
+ async onDataButtonDown(ev) {
517
+ if (undefined === ev.viewport)
518
+ return core_frontend_1.EventHandled.No; // Shouldn't really happen...
519
+ if (undefined === this._origin) {
520
+ this._origin = ev.point.clone();
521
+ this.setupAndPromptForNextAction();
522
+ return core_frontend_1.EventHandled.No;
523
+ }
524
+ await this.acceptOffset(ev);
525
+ return core_frontend_1.EventHandled.No;
526
+ }
527
+ async onInstall() { return ProjectExtentsDecoration_1.ProjectExtentsClipDecoration.allowEcefLocationChange(true); }
528
+ static async startTool() { return new ProjectGeolocationMoveTool().run(); }
529
+ }
530
+ exports.ProjectGeolocationMoveTool = ProjectGeolocationMoveTool;
531
+ ProjectGeolocationMoveTool.toolId = "ProjectLocation.Geolocation.Move";
532
+ ProjectGeolocationMoveTool.iconSpec = "icon-move"; // <== Tool button should use whatever icon you have here...
533
533
  //# sourceMappingURL=ProjectGeolocation.js.map