vim-web 0.3.44-dev.61 → 0.3.44-dev.63

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.
@@ -1,45 +1,105 @@
1
1
  import { ISignal } from "ste-signals";
2
2
  import { IVimObject, IVim } from "./vim";
3
3
  import { THREE } from "../..";
4
- export interface ISelection<T extends IVimObject> {
5
- select(object: T | T[]): void;
6
- toggle(object: T | T[]): void;
7
- add(object: T | T[]): void;
8
- remove(object: T | T[]): void;
9
- clear(): void;
10
- getAll(): T[];
11
- GetFromVim(vim: IVim<T>): T[];
12
- removeFromVim(vim: IVim<T>): void;
13
- getBoundingBox(): Promise<THREE.Box3>;
14
- count(): number;
15
- any(): boolean;
16
- has(object: T): boolean;
17
- onSelectionChanged: ISignal;
18
- }
19
4
  export interface ISelectionAdapter<T extends IVimObject> {
20
5
  outline(object: T, state: boolean): void;
21
6
  }
22
- export declare class Selection<T extends IVimObject> implements ISelection<T> {
7
+ /**
8
+ * Represents a selection manager that supports adding, removing, toggling, and querying selected objects.
9
+ * The selection change signal is debounced to dispatch only once per animation frame.
10
+ */
11
+ export declare class Selection<T extends IVimObject> {
23
12
  private _onSelectionChanged;
24
13
  private _selection;
25
14
  private _adapter;
15
+ /**
16
+ * If true, reselecting the currently selected single object will toggle it instead of doing nothing.
17
+ */
18
+ toggleOnRepeatSelect: boolean;
19
+ /**
20
+ * If true, the selection manager is enabled and can modify the selection.
21
+ */
22
+ enabled: boolean;
23
+ /**
24
+ * Creates a new Selection manager.
25
+ * @param adapter - Adapter responsible for visual selection feedback.
26
+ */
26
27
  constructor(adapter: ISelectionAdapter<T>);
28
+ /**
29
+ * Checks whether a specific object is currently selected.
30
+ * @param object - The object to check.
31
+ * @returns `true` if the object is selected; otherwise, `false`.
32
+ */
27
33
  has(object: T): boolean;
34
+ /**
35
+ * Returns the number of selected objects.
36
+ * @returns The count of selected items.
37
+ */
28
38
  count(): number;
39
+ /**
40
+ * Checks if there is at least one selected object.
41
+ * @returns `true` if the selection is not empty.
42
+ */
29
43
  any(): boolean;
44
+ /**
45
+ * Signal that fires when the selection changes.
46
+ */
30
47
  get onSelectionChanged(): ISignal;
31
- private _dispatchIfChanged;
48
+ /**
49
+ * Normalizes a value to an array of objects.
50
+ * @param oneOrMore - A single object or an array of objects.
51
+ * @returns An array of objects.
52
+ */
53
+ private toArray;
54
+ /**
55
+ * Replaces the current selection with the given object(s).
56
+ * If `toggleOnRepeatSelect` is true and the object is already the only selected one, it toggles it instead.
57
+ * @param objectOrObjects - Object(s) to select, or `undefined` to clear the selection.
58
+ */
32
59
  select(object: T): void;
33
60
  select(objects: T[]): void;
61
+ /**
62
+ * Toggles the selection state of the given object(s).
63
+ * @param objectOrObjects - Object(s) to toggle.
64
+ */
34
65
  toggle(object: T): void;
35
66
  toggle(objects: T[]): void;
67
+ /**
68
+ * Adds the given object(s) to the selection.
69
+ * @param objectOrObjects - Object(s) to add.
70
+ */
36
71
  add(object: T): void;
37
72
  add(objects: T[]): void;
73
+ /**
74
+ * Removes the given object(s) from the selection.
75
+ * @param objectOrObjects - Object(s) to remove.
76
+ */
38
77
  remove(object: T): void;
39
78
  remove(objects: T[]): void;
79
+ /**
80
+ * Clears the entire selection.
81
+ */
40
82
  clear(): void;
83
+ /**
84
+ * Returns an array of all currently selected objects.
85
+ * @returns An array of selected objects.
86
+ */
41
87
  getAll(): T[];
42
- GetFromVim(vim: IVim<T>): T[];
88
+ /**
89
+ * Returns all selected objects belonging to a specific VIM model.
90
+ * @param vim - The VIM instance to filter by.
91
+ * @returns An array of selected objects from the specified VIM.
92
+ */
93
+ getFromVim(vim: IVim<T>): T[];
94
+ /**
95
+ * Removes all selected objects that belong to a specific VIM model.
96
+ * @param vim - The VIM instance to remove selections from.
97
+ */
43
98
  removeFromVim(vim: IVim<T>): void;
99
+ /**
100
+ * Computes the bounding box that contains all selected objects.
101
+ * Skips objects that do not implement `getBoundingBox()`.
102
+ * @returns A promise resolving to the combined bounding box.
103
+ */
44
104
  getBoundingBox(): Promise<THREE.Box3>;
45
105
  }
@@ -1 +1,30 @@
1
+ import { ISignal } from 'ste-signals';
1
2
  export declare function debounce<T extends (...args: any[]) => void>(func: T, delay: number): [(...args: Parameters<T>) => void, () => void];
3
+ /**
4
+ * A debounced signal that dispatches at most once per animation frame.
5
+ */
6
+ export declare class DebouncedSignal {
7
+ private _dispatcher;
8
+ private _frameRequestId;
9
+ /**
10
+ * Indicates whether a dispatch is currently scheduled.
11
+ *
12
+ * @returns `true` if a dispatch is scheduled; otherwise `false`.
13
+ */
14
+ get isScheduled(): boolean;
15
+ /**
16
+ * Returns the signal interface that subscribers can listen to.
17
+ *
18
+ * @returns An `ISignal` that is dispatched once per frame when requested.
19
+ */
20
+ get signal(): ISignal;
21
+ /**
22
+ * Schedules the signal to be dispatched on the next animation frame.
23
+ * Has no effect if a dispatch is already scheduled.
24
+ */
25
+ requestDispatch(): void;
26
+ /**
27
+ * Cancels a scheduled signal dispatch if one exists.
28
+ */
29
+ cancel(): void;
30
+ }
@@ -50687,6 +50687,48 @@ void main() {
50687
50687
  }, delay);
50688
50688
  }, () => clearTimeout(timeoutId)];
50689
50689
  }
50690
+ class DebouncedSignal {
50691
+ constructor() {
50692
+ __publicField(this, "_dispatcher", new distExports$1.SignalDispatcher());
50693
+ __publicField(this, "_frameRequestId");
50694
+ }
50695
+ /**
50696
+ * Indicates whether a dispatch is currently scheduled.
50697
+ *
50698
+ * @returns `true` if a dispatch is scheduled; otherwise `false`.
50699
+ */
50700
+ get isScheduled() {
50701
+ return this._frameRequestId !== void 0;
50702
+ }
50703
+ /**
50704
+ * Returns the signal interface that subscribers can listen to.
50705
+ *
50706
+ * @returns An `ISignal` that is dispatched once per frame when requested.
50707
+ */
50708
+ get signal() {
50709
+ return this._dispatcher.asEvent();
50710
+ }
50711
+ /**
50712
+ * Schedules the signal to be dispatched on the next animation frame.
50713
+ * Has no effect if a dispatch is already scheduled.
50714
+ */
50715
+ requestDispatch() {
50716
+ if (this._frameRequestId !== void 0) return;
50717
+ this._frameRequestId = requestAnimationFrame(() => {
50718
+ this._dispatcher.dispatch();
50719
+ this._frameRequestId = void 0;
50720
+ });
50721
+ }
50722
+ /**
50723
+ * Cancels a scheduled signal dispatch if one exists.
50724
+ */
50725
+ cancel() {
50726
+ if (this._frameRequestId !== void 0) {
50727
+ cancelAnimationFrame(this._frameRequestId);
50728
+ this._frameRequestId = void 0;
50729
+ }
50730
+ }
50731
+ }
50690
50732
  function almostEqual(v1, v2, epsilon = 1e-6) {
50691
50733
  return Math.abs(v1.x - v2.x) < epsilon && Math.abs(v1.y - v2.y) < epsilon;
50692
50734
  }
@@ -55194,36 +55236,72 @@ void main() {
55194
55236
  }
55195
55237
  }
55196
55238
  class Selection {
55239
+ /**
55240
+ * Creates a new Selection manager.
55241
+ * @param adapter - Adapter responsible for visual selection feedback.
55242
+ */
55197
55243
  constructor(adapter) {
55198
- __publicField(this, "_onSelectionChanged", new distExports$1.SignalDispatcher());
55244
+ __publicField(this, "_onSelectionChanged", new DebouncedSignal());
55199
55245
  __publicField(this, "_selection", /* @__PURE__ */ new Set());
55200
55246
  __publicField(this, "_adapter");
55247
+ /**
55248
+ * If true, reselecting the currently selected single object will toggle it instead of doing nothing.
55249
+ */
55250
+ __publicField(this, "toggleOnRepeatSelect", false);
55251
+ /**
55252
+ * If true, the selection manager is enabled and can modify the selection.
55253
+ */
55254
+ __publicField(this, "enabled", true);
55201
55255
  this._adapter = adapter;
55202
55256
  }
55257
+ /**
55258
+ * Checks whether a specific object is currently selected.
55259
+ * @param object - The object to check.
55260
+ * @returns `true` if the object is selected; otherwise, `false`.
55261
+ */
55203
55262
  has(object) {
55204
55263
  return this._selection.has(object);
55205
55264
  }
55265
+ /**
55266
+ * Returns the number of selected objects.
55267
+ * @returns The count of selected items.
55268
+ */
55206
55269
  count() {
55207
55270
  return this._selection.size;
55208
55271
  }
55272
+ /**
55273
+ * Checks if there is at least one selected object.
55274
+ * @returns `true` if the selection is not empty.
55275
+ */
55209
55276
  any() {
55210
55277
  return this._selection.size > 0;
55211
55278
  }
55279
+ /**
55280
+ * Signal that fires when the selection changes.
55281
+ */
55212
55282
  get onSelectionChanged() {
55213
- return this._onSelectionChanged.asEvent();
55283
+ return this._onSelectionChanged.signal;
55214
55284
  }
55215
- _dispatchIfChanged(prevSize, modified) {
55216
- if (modified || this._selection.size !== prevSize) {
55217
- this._onSelectionChanged.dispatch();
55218
- }
55285
+ /**
55286
+ * Normalizes a value to an array of objects.
55287
+ * @param oneOrMore - A single object or an array of objects.
55288
+ * @returns An array of objects.
55289
+ */
55290
+ toArray(oneOrMore) {
55291
+ return Array.isArray(oneOrMore) ? oneOrMore : [oneOrMore];
55219
55292
  }
55220
55293
  select(objectOrObjects) {
55294
+ if (!this.enabled) return;
55221
55295
  if (!objectOrObjects) {
55222
55296
  this.clear();
55223
55297
  return;
55224
55298
  }
55225
- const objects = Array.isArray(objectOrObjects) ? objectOrObjects : [objectOrObjects];
55226
- if (objects.length === 1 && this._selection.size === 1 && this._selection.has(objects[0])) {
55299
+ const objects = this.toArray(objectOrObjects);
55300
+ const isRepeatSingleSelection = objects.length === 1 && this._selection.size === 1 && this._selection.has(objects[0]);
55301
+ if (isRepeatSingleSelection) {
55302
+ if (this.toggleOnRepeatSelect) {
55303
+ this.toggle(objects);
55304
+ }
55227
55305
  return;
55228
55306
  }
55229
55307
  for (const obj of this._selection) {
@@ -55234,77 +55312,105 @@ void main() {
55234
55312
  this._selection.add(obj);
55235
55313
  this._adapter.outline(obj, true);
55236
55314
  }
55237
- this._onSelectionChanged.dispatch();
55315
+ this._onSelectionChanged.requestDispatch();
55238
55316
  }
55239
55317
  toggle(objectOrObjects) {
55240
- const objects = Array.isArray(objectOrObjects) ? objectOrObjects : [objectOrObjects];
55241
- const prevSize = this._selection.size;
55242
- let modified = false;
55318
+ if (!this.enabled) return;
55319
+ const objects = this.toArray(objectOrObjects);
55320
+ let changed = false;
55243
55321
  for (const obj of objects) {
55244
55322
  if (this._selection.has(obj)) {
55245
55323
  this._selection.delete(obj);
55246
55324
  this._adapter.outline(obj, false);
55247
- modified = true;
55325
+ changed = true;
55248
55326
  } else {
55249
55327
  this._selection.add(obj);
55250
55328
  this._adapter.outline(obj, true);
55251
- modified = true;
55329
+ changed = true;
55252
55330
  }
55253
55331
  }
55254
- this._dispatchIfChanged(prevSize, modified);
55332
+ if (changed) {
55333
+ this._onSelectionChanged.requestDispatch();
55334
+ }
55255
55335
  }
55256
55336
  add(objectOrObjects) {
55257
- const objects = Array.isArray(objectOrObjects) ? objectOrObjects : [objectOrObjects];
55258
- const prevSize = this._selection.size;
55259
- let anyNew = false;
55337
+ if (!this.enabled) return;
55338
+ const objects = this.toArray(objectOrObjects);
55339
+ let changed = false;
55260
55340
  for (const obj of objects) {
55261
55341
  if (!this._selection.has(obj)) {
55262
55342
  this._selection.add(obj);
55263
55343
  this._adapter.outline(obj, true);
55264
- anyNew = true;
55344
+ changed = true;
55265
55345
  }
55266
55346
  }
55267
- this._dispatchIfChanged(prevSize, anyNew);
55347
+ if (changed) {
55348
+ this._onSelectionChanged.requestDispatch();
55349
+ }
55268
55350
  }
55269
55351
  remove(objectOrObjects) {
55270
- const objects = Array.isArray(objectOrObjects) ? objectOrObjects : [objectOrObjects];
55271
- const prevSize = this._selection.size;
55272
- let removedAny = false;
55352
+ if (!this.enabled) return;
55353
+ const objects = this.toArray(objectOrObjects);
55354
+ let changed = false;
55273
55355
  for (const obj of objects) {
55274
55356
  if (this._selection.delete(obj)) {
55275
55357
  this._adapter.outline(obj, false);
55276
- removedAny = true;
55358
+ changed = true;
55277
55359
  }
55278
55360
  }
55279
- this._dispatchIfChanged(prevSize, removedAny);
55361
+ if (changed) {
55362
+ this._onSelectionChanged.requestDispatch();
55363
+ }
55280
55364
  }
55365
+ /**
55366
+ * Clears the entire selection.
55367
+ */
55281
55368
  clear() {
55282
- if (this._selection.size > 0) {
55283
- for (const obj of this._selection) {
55284
- this._adapter.outline(obj, false);
55285
- }
55286
- this._selection.clear();
55287
- this._onSelectionChanged.dispatch();
55369
+ if (!this.enabled) return;
55370
+ if (this._selection.size === 0) return;
55371
+ for (const obj of this._selection) {
55372
+ this._adapter.outline(obj, false);
55288
55373
  }
55374
+ this._selection.clear();
55375
+ this._onSelectionChanged.requestDispatch();
55289
55376
  }
55377
+ /**
55378
+ * Returns an array of all currently selected objects.
55379
+ * @returns An array of selected objects.
55380
+ */
55290
55381
  getAll() {
55291
55382
  return [...this._selection];
55292
55383
  }
55293
- GetFromVim(vim) {
55384
+ /**
55385
+ * Returns all selected objects belonging to a specific VIM model.
55386
+ * @param vim - The VIM instance to filter by.
55387
+ * @returns An array of selected objects from the specified VIM.
55388
+ */
55389
+ getFromVim(vim) {
55294
55390
  return [...this._selection].filter((obj) => obj.vim === vim);
55295
55391
  }
55392
+ /**
55393
+ * Removes all selected objects that belong to a specific VIM model.
55394
+ * @param vim - The VIM instance to remove selections from.
55395
+ */
55296
55396
  removeFromVim(vim) {
55297
- const prevSize = this._selection.size;
55298
- let removed = false;
55397
+ let changed = false;
55299
55398
  for (const obj of [...this._selection]) {
55300
55399
  if (obj.vim === vim) {
55301
55400
  this._selection.delete(obj);
55302
55401
  this._adapter.outline(obj, false);
55303
- removed = true;
55402
+ changed = true;
55304
55403
  }
55305
55404
  }
55306
- this._dispatchIfChanged(prevSize, removed);
55405
+ if (changed) {
55406
+ this._onSelectionChanged.requestDispatch();
55407
+ }
55307
55408
  }
55409
+ /**
55410
+ * Computes the bounding box that contains all selected objects.
55411
+ * Skips objects that do not implement `getBoundingBox()`.
55412
+ * @returns A promise resolving to the combined bounding box.
55413
+ */
55308
55414
  async getBoundingBox() {
55309
55415
  var _a3;
55310
55416
  const box = new Box3();