lythreeframe 1.2.62 → 1.2.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.
@@ -125,6 +125,30 @@ exports.AttachmentRules = void 0;
125
125
  AttachmentRules[AttachmentRules["KeepRelative"] = 2] = "KeepRelative";
126
126
  })(exports.AttachmentRules || (exports.AttachmentRules = {}));
127
127
 
128
+ class Delegate {
129
+ constructor() {
130
+ this.functions = [];
131
+ }
132
+ broadcast(...args) {
133
+ this.functions.forEach((func) => func(...args));
134
+ }
135
+ add(func) {
136
+ this.functions.push(func);
137
+ }
138
+ remove(func) {
139
+ const index = this.functions.indexOf(func);
140
+ if (index >= 0) {
141
+ this.functions.splice(index, 1);
142
+ }
143
+ else {
144
+ console.warn("function not found");
145
+ }
146
+ }
147
+ clear() {
148
+ this.functions = [];
149
+ }
150
+ }
151
+
128
152
  class SceneComponent extends Component {
129
153
  set parentActor(value) {
130
154
  this.childrenComponents.forEach((elem) => {
@@ -135,6 +159,11 @@ class SceneComponent extends Component {
135
159
  get parentActor() {
136
160
  return this._parentActor;
137
161
  }
162
+ // Delegate getters
163
+ get onHoverBeginDelegate() { return this._onHoverBeginDelegate; }
164
+ get onHoverEndDelegate() { return this._onHoverEndDelegate; }
165
+ get onClickDelegate() { return this._onClickDelegate; }
166
+ get onDoubleClickDelegate() { return this._onDoubleClickDelegate; }
138
167
  get world() {
139
168
  return this.app.world;
140
169
  }
@@ -142,6 +171,11 @@ class SceneComponent extends Component {
142
171
  super(uuid);
143
172
  this.bCanHover = false;
144
173
  this.bCanClick = false;
174
+ // Component 级别事件 Delegates
175
+ this._onHoverBeginDelegate = new Delegate();
176
+ this._onHoverEndDelegate = new Delegate();
177
+ this._onClickDelegate = new Delegate();
178
+ this._onDoubleClickDelegate = new Delegate();
145
179
  this.app = app;
146
180
  this.name = "SceneComponent";
147
181
  }
@@ -710,38 +744,17 @@ class SceneComponent extends Component {
710
744
  return this.bCanClick;
711
745
  }
712
746
  onHorveringBegin() {
713
- if (!this.isHoverEnabled) {
714
- return;
715
- }
716
- if (this.parentActor) {
717
- let comp = this;
718
- this.parentActor.onComponentHorveringBegin(comp);
719
- }
747
+ this._onHoverBeginDelegate.broadcast();
720
748
  }
721
749
  onHorveringEnd() {
722
- if (!this.isHoverEnabled) {
723
- return;
724
- }
725
- if (this.parentActor) {
726
- let comp = this;
727
- this.parentActor.onComponentHorveringEnd(comp);
728
- }
750
+ this._onHoverEndDelegate.broadcast();
729
751
  }
730
752
  /* click */
731
753
  onClicked() {
732
- if (!this.isClickEnabled) {
733
- return;
734
- }
735
- if (this.parentActor) {
736
- let comp = this;
737
- this.parentActor.onComponentClicked(comp);
738
- }
754
+ this._onClickDelegate.broadcast();
739
755
  }
740
756
  onDoubleClicked() {
741
- if (this.parentActor) {
742
- let comp = this;
743
- this.parentActor.onComponentDoubleClicked(comp);
744
- }
757
+ this._onDoubleClickDelegate.broadcast();
745
758
  }
746
759
  }
747
760
 
@@ -1301,30 +1314,6 @@ exports.AssetType = void 0;
1301
1314
  AssetType[AssetType["undefined"] = -1] = "undefined";
1302
1315
  })(exports.AssetType || (exports.AssetType = {}));
1303
1316
 
1304
- class Delegate {
1305
- constructor() {
1306
- this.functions = [];
1307
- }
1308
- broadcast(...args) {
1309
- this.functions.forEach((func) => func(...args));
1310
- }
1311
- add(func) {
1312
- this.functions.push(func);
1313
- }
1314
- remove(func) {
1315
- const index = this.functions.indexOf(func);
1316
- if (index >= 0) {
1317
- this.functions.splice(index, 1);
1318
- }
1319
- else {
1320
- console.warn("function not found");
1321
- }
1322
- }
1323
- clear() {
1324
- this.functions = [];
1325
- }
1326
- }
1327
-
1328
1317
  const DefaultPostProcessParam = {
1329
1318
  steps: []
1330
1319
  };
@@ -2191,34 +2180,51 @@ class Controller {
2191
2180
  get world() { return this._app.world; }
2192
2181
  get viewPort() { return this._app.viewport; }
2193
2182
  get app() { return this._app; }
2194
- get onClickNothingDelegate() { return this._onClickNothingDelegate; }
2195
- get onComponentClickDelegate() { return this._onComponentClickDelegate; }
2196
- get onComponentDoubleClickDelegate() { return this._onComponentDoubleClickDelegate; }
2197
- get onComponentHoverBeginDelegate() { return this._onComponentHoverBeginDelegate; }
2198
- get onComponentHoverEndDelegate() { return this._onComponentHoverEndDelegate; }
2199
- get onComponentPointerDownDelegate() { return this._onComponentPointerDownDelegate; }
2200
2183
  get pawn() {
2201
2184
  if (!this._pawn)
2202
2185
  throw Error("pawn is null");
2203
2186
  return this._pawn;
2204
2187
  }
2188
+ // Component level delegate getters
2189
+ get onComponentClickDelegate() { return this._onComponentClickDelegate; }
2190
+ get onComponentDoubleClickDelegate() { return this._onComponentDoubleClickDelegate; }
2191
+ get onComponentHoverBeginDelegate() { return this._onComponentHoverBeginDelegate; }
2192
+ get onComponentHoverEndDelegate() { return this._onComponentHoverEndDelegate; }
2193
+ get onComponentPointerDownDelegate() { return this._onComponentPointerDownDelegate; }
2194
+ // Actor level delegate getters
2195
+ get onActorClickDelegate() { return this._onActorClickDelegate; }
2196
+ get onActorDoubleClickDelegate() { return this._onActorDoubleClickDelegate; }
2197
+ get onActorHoverBeginDelegate() { return this._onActorHoverBeginDelegate; }
2198
+ get onActorHoverEndDelegate() { return this._onActorHoverEndDelegate; }
2199
+ get onClickNothingDelegate() { return this._onClickNothingDelegate; }
2205
2200
  constructor(app) {
2206
2201
  this._pawn = null;
2202
+ // Component level state
2203
+ this.hoveringComponent = null;
2204
+ // Actor level state
2205
+ this.hoveringActor = null;
2206
+ // Click state
2207
2207
  this.prepareClickComponent = null;
2208
2208
  this.prepareClickHit = null;
2209
2209
  this.prepareClickModifiers = { ctrlKey: false, shiftKey: false, altKey: false };
2210
- this.hoveringComponent = null;
2211
2210
  this._pointButtonIsDown = new Set();
2212
- this._onClickNothingDelegate = new Delegate();
2211
+ // Component level delegates
2213
2212
  this._onComponentClickDelegate = new Delegate();
2214
2213
  this._onComponentDoubleClickDelegate = new Delegate();
2215
2214
  this._onComponentHoverBeginDelegate = new Delegate();
2216
2215
  this._onComponentHoverEndDelegate = new Delegate();
2217
2216
  this._onComponentPointerDownDelegate = new Delegate();
2217
+ // Actor level delegates
2218
+ this._onActorClickDelegate = new Delegate();
2219
+ this._onActorDoubleClickDelegate = new Delegate();
2220
+ this._onActorHoverBeginDelegate = new Delegate();
2221
+ this._onActorHoverEndDelegate = new Delegate();
2222
+ // Other delegates
2223
+ this._onClickNothingDelegate = new Delegate();
2218
2224
  // Pointer state
2219
2225
  this.pointerPosition = new webgpu.Vector2();
2220
2226
  this.pointerLeftDownPosition = new webgpu.Vector2();
2221
- // Reusable objects to avoid GC pressure
2227
+ // Reusable objects
2222
2228
  this._tempVec2 = new webgpu.Vector2();
2223
2229
  this._raycastVec2 = new webgpu.Vector2();
2224
2230
  // Double click detection
@@ -2257,7 +2263,7 @@ class Controller {
2257
2263
  }
2258
2264
  destroy() {
2259
2265
  this.clearClickTimer();
2260
- this.clearHoveringComponent();
2266
+ this.clearHovering();
2261
2267
  const canvas = this.viewPort.canvas;
2262
2268
  if (canvas) {
2263
2269
  canvas.removeEventListener("pointerenter", this.onPointerEnter);
@@ -2268,7 +2274,9 @@ class Controller {
2268
2274
  this.pawn.destroy();
2269
2275
  this._pawn = null;
2270
2276
  }
2277
+ // ==================== Pointer Events ====================
2271
2278
  onPointerMoveEvent(event) {
2279
+ var _a, _b;
2272
2280
  const canvas = this.viewPort.canvas;
2273
2281
  if (!canvas)
2274
2282
  throw Error("canvas is null");
@@ -2277,47 +2285,48 @@ class Controller {
2277
2285
  if (this._pointButtonIsDown.size > 0)
2278
2286
  return;
2279
2287
  const hits = this.getHitResultUnderCursor();
2280
- const component = hits === null || hits === void 0 ? void 0 : hits.component;
2288
+ const component = (_a = hits === null || hits === void 0 ? void 0 : hits.component) !== null && _a !== void 0 ? _a : null;
2289
+ const actor = (_b = component === null || component === void 0 ? void 0 : component.parentActor) !== null && _b !== void 0 ? _b : null;
2290
+ // Component 级别 hover 检测
2281
2291
  if (component !== this.hoveringComponent) {
2282
- this.clearHoveringComponent();
2283
- if (component instanceof SceneComponent && component.isHoverEnabled && hits) {
2284
- this.fireHoverEvent(component, hits.hit, true);
2292
+ if (this.hoveringComponent) {
2293
+ this.fireComponentHoverEnd(this.hoveringComponent);
2294
+ }
2295
+ if (component && component.isHoverEnabled && hits) {
2296
+ this.fireComponentHoverBegin(component, hits.hit);
2297
+ }
2298
+ }
2299
+ // Actor 级别 hover 检测(独立于 Component)
2300
+ if (actor !== this.hoveringActor) {
2301
+ if (this.hoveringActor && this.hoveringComponent) {
2302
+ this.fireActorHoverEnd(this.hoveringActor, this.hoveringComponent);
2303
+ }
2304
+ if (actor && component && actor.isHoverEnabled && hits) {
2305
+ this.fireActorHoverBegin(actor, component, hits.hit);
2285
2306
  }
2286
2307
  }
2308
+ this.hoveringComponent = component;
2309
+ this.hoveringActor = actor;
2287
2310
  }
2288
- clearHoveringComponent() {
2311
+ clearHovering() {
2289
2312
  if (this.hoveringComponent) {
2290
- this.fireHoverEvent(this.hoveringComponent, null, false);
2313
+ this.fireComponentHoverEnd(this.hoveringComponent);
2291
2314
  }
2292
- }
2293
- fireHoverEvent(component, hit, isBegin) {
2294
- const event = { component, hit, handled: false };
2295
- if (isBegin) {
2296
- this._onComponentHoverBeginDelegate.broadcast(event);
2297
- if (!event.handled) {
2298
- component.onHorveringBegin();
2299
- }
2300
- this.hoveringComponent = component;
2301
- }
2302
- else {
2303
- this._onComponentHoverEndDelegate.broadcast(event);
2304
- if (!event.handled) {
2305
- component.onHorveringEnd();
2306
- }
2307
- this.hoveringComponent = null;
2315
+ if (this.hoveringActor && this.hoveringComponent) {
2316
+ this.fireActorHoverEnd(this.hoveringActor, this.hoveringComponent);
2308
2317
  }
2318
+ this.hoveringComponent = null;
2319
+ this.hoveringActor = null;
2309
2320
  }
2310
2321
  onPointerUpEvent(event) {
2311
2322
  this._pointButtonIsDown.delete(event.button);
2312
2323
  if (event.button !== 0)
2313
2324
  return;
2314
- // Check if pointer moved too much (drag instead of click)
2315
2325
  const pointerOffset = this._tempVec2.subVectors(this.pointerLeftDownPosition, this.pointerPosition).length();
2316
2326
  if (pointerOffset > 0.005) {
2317
2327
  this.clearClickTimer();
2318
2328
  return;
2319
2329
  }
2320
- // 保存修饰键状态
2321
2330
  this.prepareClickModifiers = {
2322
2331
  ctrlKey: event.ctrlKey,
2323
2332
  shiftKey: event.shiftKey,
@@ -2339,7 +2348,7 @@ class Controller {
2339
2348
  this.leftClickTimer = window.setTimeout(() => {
2340
2349
  this.leftClickTimer = null;
2341
2350
  if (this.prepareClickComponent && this.prepareClickHit) {
2342
- this.fireClickEvent(this.prepareClickComponent, this.prepareClickHit, false, this.prepareClickModifiers);
2351
+ this.fireClickEvents(this.prepareClickComponent, this.prepareClickHit, false);
2343
2352
  this.prepareClickComponent = null;
2344
2353
  this.prepareClickHit = null;
2345
2354
  }
@@ -2352,7 +2361,7 @@ class Controller {
2352
2361
  handleDoubleClick() {
2353
2362
  this.clearClickTimer();
2354
2363
  if (this.prepareClickComponent && this.prepareClickHit) {
2355
- this.fireClickEvent(this.prepareClickComponent, this.prepareClickHit, true, this.prepareClickModifiers);
2364
+ this.fireClickEvents(this.prepareClickComponent, this.prepareClickHit, true);
2356
2365
  }
2357
2366
  else {
2358
2367
  this._onClickNothingDelegate.broadcast();
@@ -2360,8 +2369,40 @@ class Controller {
2360
2369
  this.prepareClickComponent = null;
2361
2370
  this.prepareClickHit = null;
2362
2371
  }
2363
- fireClickEvent(component, hit, isDoubleClick, modifiers) {
2364
- const event = Object.assign({ component, hit, handled: false }, modifiers);
2372
+ onPointerDownEvent(event) {
2373
+ this._pointButtonIsDown.add(event.button);
2374
+ if (event.button === 0) {
2375
+ this.pointerLeftDownPosition.copy(this.pointerPosition);
2376
+ }
2377
+ const hit = this.getHitResultUnderCursor();
2378
+ const component = hit === null || hit === void 0 ? void 0 : hit.component;
2379
+ if (component instanceof SceneComponent && hit) {
2380
+ this.firePointerDownEvent(component, hit.hit, event.button);
2381
+ }
2382
+ }
2383
+ onPointerEnterEvent(_event) {
2384
+ this.addCorePointerListeners();
2385
+ }
2386
+ onPointerLeaveEvent(_event) {
2387
+ this.removeCorePointerListeners();
2388
+ }
2389
+ // ==================== Component Level Events ====================
2390
+ fireComponentHoverBegin(component, hit) {
2391
+ const event = { component, hit, handled: false };
2392
+ this._onComponentHoverBeginDelegate.broadcast(event);
2393
+ if (!event.handled) {
2394
+ component.onHorveringBegin();
2395
+ }
2396
+ }
2397
+ fireComponentHoverEnd(component) {
2398
+ const event = { component, hit: null, handled: false };
2399
+ this._onComponentHoverEndDelegate.broadcast(event);
2400
+ if (!event.handled) {
2401
+ component.onHorveringEnd();
2402
+ }
2403
+ }
2404
+ fireComponentClick(component, hit, isDoubleClick) {
2405
+ const event = Object.assign({ component, hit, handled: false }, this.prepareClickModifiers);
2365
2406
  if (isDoubleClick) {
2366
2407
  this._onComponentDoubleClickDelegate.broadcast(event);
2367
2408
  if (!event.handled) {
@@ -2375,33 +2416,56 @@ class Controller {
2375
2416
  }
2376
2417
  }
2377
2418
  }
2378
- clearClickTimer() {
2379
- if (this.leftClickTimer) {
2380
- window.clearTimeout(this.leftClickTimer);
2381
- this.leftClickTimer = null;
2382
- }
2419
+ firePointerDownEvent(component, hit, button) {
2420
+ const event = { component, hit, button, handled: false };
2421
+ this._onComponentPointerDownDelegate.broadcast(event);
2383
2422
  }
2384
- onPointerDownEvent(event) {
2385
- this._pointButtonIsDown.add(event.button);
2386
- if (event.button === 0) {
2387
- this.pointerLeftDownPosition.copy(this.pointerPosition);
2423
+ // ==================== Actor Level Events ====================
2424
+ fireActorHoverBegin(actor, component, hit) {
2425
+ const event = { actor, component, hit, handled: false };
2426
+ this._onActorHoverBeginDelegate.broadcast(event);
2427
+ if (!event.handled) {
2428
+ actor.onActorHoverBegin(component);
2388
2429
  }
2389
- // 广播组件按下事件
2390
- const hit = this.getHitResultUnderCursor();
2391
- const component = hit === null || hit === void 0 ? void 0 : hit.component;
2392
- if (component instanceof SceneComponent && hit) {
2393
- this.firePointerDownEvent(component, hit.hit, event.button);
2430
+ }
2431
+ fireActorHoverEnd(actor, component) {
2432
+ const event = { actor, component, hit: null, handled: false };
2433
+ this._onActorHoverEndDelegate.broadcast(event);
2434
+ if (!event.handled) {
2435
+ actor.onActorHoverEnd(component);
2394
2436
  }
2395
2437
  }
2396
- firePointerDownEvent(component, hit, button) {
2397
- const event = { component, hit, button, handled: false };
2398
- this._onComponentPointerDownDelegate.broadcast(event);
2438
+ fireActorClick(actor, component, hit, isDoubleClick) {
2439
+ const event = Object.assign({ actor, component, hit, handled: false }, this.prepareClickModifiers);
2440
+ if (isDoubleClick) {
2441
+ this._onActorDoubleClickDelegate.broadcast(event);
2442
+ if (!event.handled) {
2443
+ actor.onActorDoubleClick(component);
2444
+ }
2445
+ }
2446
+ else {
2447
+ this._onActorClickDelegate.broadcast(event);
2448
+ if (!event.handled) {
2449
+ actor.onActorClick(component);
2450
+ }
2451
+ }
2399
2452
  }
2400
- onPointerEnterEvent(_event) {
2401
- this.addCorePointerListeners();
2453
+ // ==================== Combined Events ====================
2454
+ fireClickEvents(component, hit, isDoubleClick) {
2455
+ // Component level
2456
+ this.fireComponentClick(component, hit, isDoubleClick);
2457
+ // Actor level
2458
+ const actor = component.parentActor;
2459
+ if (actor && actor.isClickEnabled) {
2460
+ this.fireActorClick(actor, component, hit, isDoubleClick);
2461
+ }
2402
2462
  }
2403
- onPointerLeaveEvent(_event) {
2404
- this.removeCorePointerListeners();
2463
+ // ==================== Utility ====================
2464
+ clearClickTimer() {
2465
+ if (this.leftClickTimer) {
2466
+ window.clearTimeout(this.leftClickTimer);
2467
+ this.leftClickTimer = null;
2468
+ }
2405
2469
  }
2406
2470
  addCorePointerListeners() {
2407
2471
  const canvas = this.viewPort.canvas;
@@ -2437,17 +2501,14 @@ class Controller {
2437
2501
  this._raycastVec2.set(x, y);
2438
2502
  this.raycaster.setFromCamera(this._raycastVec2, this.camera);
2439
2503
  const hits = this.raycaster.intersectObjects(this.world.scene.children, true);
2440
- let out = [];
2504
+ const out = [];
2441
2505
  for (const hit of hits) {
2442
2506
  if (hit.object.userData["rayIgnored"])
2443
2507
  continue;
2444
2508
  const component = hit.object.userData["LYObject"];
2445
2509
  if (!component)
2446
2510
  continue;
2447
- out.push({
2448
- component: component,
2449
- hit: hit
2450
- });
2511
+ out.push({ component, hit });
2451
2512
  }
2452
2513
  return out;
2453
2514
  }
@@ -2640,15 +2701,21 @@ class Actor extends BaseObject {
2640
2701
  this.app.world.removeTickableActor(this);
2641
2702
  }
2642
2703
  }
2704
+ // Delegate getters
2705
+ get onHoverBeginDelegate() { return this._onHoverBeginDelegate; }
2706
+ get onHoverEndDelegate() { return this._onHoverEndDelegate; }
2707
+ get onClickDelegate() { return this._onClickDelegate; }
2708
+ get onDoubleClickDelegate() { return this._onDoubleClickDelegate; }
2643
2709
  constructor(app, uuid) {
2644
2710
  super(uuid);
2645
2711
  this._name = "Actor";
2646
2712
  this._rootComponent = null;
2647
2713
  this._world = null;
2648
- this.onClickedEvent = [];
2649
- this.onDoubleClickedEvent = [];
2650
- this.onHoverBeginEvent = [];
2651
- this.onHoverEndEvent = [];
2714
+ // Actor 级别事件 Delegates
2715
+ this._onHoverBeginDelegate = new Delegate();
2716
+ this._onHoverEndDelegate = new Delegate();
2717
+ this._onClickDelegate = new Delegate();
2718
+ this._onDoubleClickDelegate = new Delegate();
2652
2719
  this.app = app;
2653
2720
  this.rootComponent = this.constructRootComponent();
2654
2721
  this.rootComponent.parentActor = this;
@@ -2903,80 +2970,18 @@ class Actor extends BaseObject {
2903
2970
  set isClickEnabled(bCanHorver) {
2904
2971
  this.rootComponent.isClickEnabled = bCanHorver;
2905
2972
  }
2906
- // hovering begin
2907
- addHoveringBeginEvent(newFunc) {
2908
- this.onHoverBeginEvent.push(newFunc);
2909
- }
2910
- removeHoveringBeginEvent(target) {
2911
- let index = this.onHoverBeginEvent.indexOf(target);
2912
- if (index >= 0) {
2913
- this.onHoverBeginEvent.splice(index, 1);
2914
- }
2915
- }
2916
- clearHoveringBeginEvent() {
2917
- this.onHoverBeginEvent = [];
2918
- }
2919
- onComponentHorveringBegin(component) {
2920
- for (let i = 0; i < this.onHoverBeginEvent.length; ++i) {
2921
- this.onHoverBeginEvent[i](component);
2922
- }
2923
- }
2924
- // hovering end
2925
- addHoveringEndEvent(newFunc) {
2926
- this.onHoverEndEvent.push(newFunc);
2927
- }
2928
- removeHoveringEndEvent(target) {
2929
- let index = this.onHoverEndEvent.indexOf(target);
2930
- if (index >= 0) {
2931
- this.onHoverEndEvent.splice(index, 1);
2932
- }
2933
- }
2934
- clearHoveringEndEvent() {
2935
- this.onHoverEndEvent = [];
2936
- }
2937
- onComponentHorveringEnd(component) {
2938
- // console.log("onComponentHorveringEnd", this)
2939
- for (let i = 0; i < this.onHoverEndEvent.length; ++i) {
2940
- this.onHoverEndEvent[i](component);
2941
- }
2942
- }
2943
- //click
2944
- addClickEvent(newFunc) {
2945
- this.onClickedEvent.push(newFunc);
2946
- }
2947
- removeClickEvent(target) {
2948
- let index = this.onClickedEvent.indexOf(target);
2949
- if (index >= 0) {
2950
- this.onClickedEvent.splice(index, 1);
2951
- }
2952
- }
2953
- clearClickEvent() {
2954
- this.onClickedEvent = [];
2973
+ // ==================== Actor Events ====================
2974
+ onActorHoverBegin(component) {
2975
+ this._onHoverBeginDelegate.broadcast(component);
2955
2976
  }
2956
- onComponentClicked(component) {
2957
- //console.log("onComponentClicked", this.Name, component)
2958
- for (let i = 0; i < this.onClickedEvent.length; ++i) {
2959
- this.onClickedEvent[i](component);
2960
- }
2977
+ onActorHoverEnd(component) {
2978
+ this._onHoverEndDelegate.broadcast(component);
2961
2979
  }
2962
- // double click
2963
- addDoubleClickEvent(newFunc) {
2964
- this.onDoubleClickedEvent.push(newFunc);
2965
- }
2966
- removeDoubleClickEvent(target) {
2967
- let index = this.onClickedEvent.indexOf(target);
2968
- if (index >= 0) {
2969
- this.onDoubleClickedEvent.splice(index, 1);
2970
- }
2971
- }
2972
- onComponentDoubleClicked(component) {
2973
- //console.log("onComponentClicked", this.Name, component)
2974
- for (let i = 0; i < this.onDoubleClickedEvent.length; ++i) {
2975
- this.onDoubleClickedEvent[i](component);
2976
- }
2980
+ onActorClick(component) {
2981
+ this._onClickDelegate.broadcast(component);
2977
2982
  }
2978
- clearDoubleClickEvent() {
2979
- this.onDoubleClickedEvent = [];
2983
+ onActorDoubleClick(component) {
2984
+ this._onDoubleClickDelegate.broadcast(component);
2980
2985
  }
2981
2986
  }
2982
2987
 
@@ -123,6 +123,30 @@ var AttachmentRules;
123
123
  AttachmentRules[AttachmentRules["KeepRelative"] = 2] = "KeepRelative";
124
124
  })(AttachmentRules || (AttachmentRules = {}));
125
125
 
126
+ class Delegate {
127
+ constructor() {
128
+ this.functions = [];
129
+ }
130
+ broadcast(...args) {
131
+ this.functions.forEach((func) => func(...args));
132
+ }
133
+ add(func) {
134
+ this.functions.push(func);
135
+ }
136
+ remove(func) {
137
+ const index = this.functions.indexOf(func);
138
+ if (index >= 0) {
139
+ this.functions.splice(index, 1);
140
+ }
141
+ else {
142
+ console.warn("function not found");
143
+ }
144
+ }
145
+ clear() {
146
+ this.functions = [];
147
+ }
148
+ }
149
+
126
150
  class SceneComponent extends Component {
127
151
  set parentActor(value) {
128
152
  this.childrenComponents.forEach((elem) => {
@@ -133,6 +157,11 @@ class SceneComponent extends Component {
133
157
  get parentActor() {
134
158
  return this._parentActor;
135
159
  }
160
+ // Delegate getters
161
+ get onHoverBeginDelegate() { return this._onHoverBeginDelegate; }
162
+ get onHoverEndDelegate() { return this._onHoverEndDelegate; }
163
+ get onClickDelegate() { return this._onClickDelegate; }
164
+ get onDoubleClickDelegate() { return this._onDoubleClickDelegate; }
136
165
  get world() {
137
166
  return this.app.world;
138
167
  }
@@ -140,6 +169,11 @@ class SceneComponent extends Component {
140
169
  super(uuid);
141
170
  this.bCanHover = false;
142
171
  this.bCanClick = false;
172
+ // Component 级别事件 Delegates
173
+ this._onHoverBeginDelegate = new Delegate();
174
+ this._onHoverEndDelegate = new Delegate();
175
+ this._onClickDelegate = new Delegate();
176
+ this._onDoubleClickDelegate = new Delegate();
143
177
  this.app = app;
144
178
  this.name = "SceneComponent";
145
179
  }
@@ -708,38 +742,17 @@ class SceneComponent extends Component {
708
742
  return this.bCanClick;
709
743
  }
710
744
  onHorveringBegin() {
711
- if (!this.isHoverEnabled) {
712
- return;
713
- }
714
- if (this.parentActor) {
715
- let comp = this;
716
- this.parentActor.onComponentHorveringBegin(comp);
717
- }
745
+ this._onHoverBeginDelegate.broadcast();
718
746
  }
719
747
  onHorveringEnd() {
720
- if (!this.isHoverEnabled) {
721
- return;
722
- }
723
- if (this.parentActor) {
724
- let comp = this;
725
- this.parentActor.onComponentHorveringEnd(comp);
726
- }
748
+ this._onHoverEndDelegate.broadcast();
727
749
  }
728
750
  /* click */
729
751
  onClicked() {
730
- if (!this.isClickEnabled) {
731
- return;
732
- }
733
- if (this.parentActor) {
734
- let comp = this;
735
- this.parentActor.onComponentClicked(comp);
736
- }
752
+ this._onClickDelegate.broadcast();
737
753
  }
738
754
  onDoubleClicked() {
739
- if (this.parentActor) {
740
- let comp = this;
741
- this.parentActor.onComponentDoubleClicked(comp);
742
- }
755
+ this._onDoubleClickDelegate.broadcast();
743
756
  }
744
757
  }
745
758
 
@@ -1299,30 +1312,6 @@ var AssetType;
1299
1312
  AssetType[AssetType["undefined"] = -1] = "undefined";
1300
1313
  })(AssetType || (AssetType = {}));
1301
1314
 
1302
- class Delegate {
1303
- constructor() {
1304
- this.functions = [];
1305
- }
1306
- broadcast(...args) {
1307
- this.functions.forEach((func) => func(...args));
1308
- }
1309
- add(func) {
1310
- this.functions.push(func);
1311
- }
1312
- remove(func) {
1313
- const index = this.functions.indexOf(func);
1314
- if (index >= 0) {
1315
- this.functions.splice(index, 1);
1316
- }
1317
- else {
1318
- console.warn("function not found");
1319
- }
1320
- }
1321
- clear() {
1322
- this.functions = [];
1323
- }
1324
- }
1325
-
1326
1315
  const DefaultPostProcessParam = {
1327
1316
  steps: []
1328
1317
  };
@@ -2189,34 +2178,51 @@ class Controller {
2189
2178
  get world() { return this._app.world; }
2190
2179
  get viewPort() { return this._app.viewport; }
2191
2180
  get app() { return this._app; }
2192
- get onClickNothingDelegate() { return this._onClickNothingDelegate; }
2193
- get onComponentClickDelegate() { return this._onComponentClickDelegate; }
2194
- get onComponentDoubleClickDelegate() { return this._onComponentDoubleClickDelegate; }
2195
- get onComponentHoverBeginDelegate() { return this._onComponentHoverBeginDelegate; }
2196
- get onComponentHoverEndDelegate() { return this._onComponentHoverEndDelegate; }
2197
- get onComponentPointerDownDelegate() { return this._onComponentPointerDownDelegate; }
2198
2181
  get pawn() {
2199
2182
  if (!this._pawn)
2200
2183
  throw Error("pawn is null");
2201
2184
  return this._pawn;
2202
2185
  }
2186
+ // Component level delegate getters
2187
+ get onComponentClickDelegate() { return this._onComponentClickDelegate; }
2188
+ get onComponentDoubleClickDelegate() { return this._onComponentDoubleClickDelegate; }
2189
+ get onComponentHoverBeginDelegate() { return this._onComponentHoverBeginDelegate; }
2190
+ get onComponentHoverEndDelegate() { return this._onComponentHoverEndDelegate; }
2191
+ get onComponentPointerDownDelegate() { return this._onComponentPointerDownDelegate; }
2192
+ // Actor level delegate getters
2193
+ get onActorClickDelegate() { return this._onActorClickDelegate; }
2194
+ get onActorDoubleClickDelegate() { return this._onActorDoubleClickDelegate; }
2195
+ get onActorHoverBeginDelegate() { return this._onActorHoverBeginDelegate; }
2196
+ get onActorHoverEndDelegate() { return this._onActorHoverEndDelegate; }
2197
+ get onClickNothingDelegate() { return this._onClickNothingDelegate; }
2203
2198
  constructor(app) {
2204
2199
  this._pawn = null;
2200
+ // Component level state
2201
+ this.hoveringComponent = null;
2202
+ // Actor level state
2203
+ this.hoveringActor = null;
2204
+ // Click state
2205
2205
  this.prepareClickComponent = null;
2206
2206
  this.prepareClickHit = null;
2207
2207
  this.prepareClickModifiers = { ctrlKey: false, shiftKey: false, altKey: false };
2208
- this.hoveringComponent = null;
2209
2208
  this._pointButtonIsDown = new Set();
2210
- this._onClickNothingDelegate = new Delegate();
2209
+ // Component level delegates
2211
2210
  this._onComponentClickDelegate = new Delegate();
2212
2211
  this._onComponentDoubleClickDelegate = new Delegate();
2213
2212
  this._onComponentHoverBeginDelegate = new Delegate();
2214
2213
  this._onComponentHoverEndDelegate = new Delegate();
2215
2214
  this._onComponentPointerDownDelegate = new Delegate();
2215
+ // Actor level delegates
2216
+ this._onActorClickDelegate = new Delegate();
2217
+ this._onActorDoubleClickDelegate = new Delegate();
2218
+ this._onActorHoverBeginDelegate = new Delegate();
2219
+ this._onActorHoverEndDelegate = new Delegate();
2220
+ // Other delegates
2221
+ this._onClickNothingDelegate = new Delegate();
2216
2222
  // Pointer state
2217
2223
  this.pointerPosition = new Vector2();
2218
2224
  this.pointerLeftDownPosition = new Vector2();
2219
- // Reusable objects to avoid GC pressure
2225
+ // Reusable objects
2220
2226
  this._tempVec2 = new Vector2();
2221
2227
  this._raycastVec2 = new Vector2();
2222
2228
  // Double click detection
@@ -2255,7 +2261,7 @@ class Controller {
2255
2261
  }
2256
2262
  destroy() {
2257
2263
  this.clearClickTimer();
2258
- this.clearHoveringComponent();
2264
+ this.clearHovering();
2259
2265
  const canvas = this.viewPort.canvas;
2260
2266
  if (canvas) {
2261
2267
  canvas.removeEventListener("pointerenter", this.onPointerEnter);
@@ -2266,7 +2272,9 @@ class Controller {
2266
2272
  this.pawn.destroy();
2267
2273
  this._pawn = null;
2268
2274
  }
2275
+ // ==================== Pointer Events ====================
2269
2276
  onPointerMoveEvent(event) {
2277
+ var _a, _b;
2270
2278
  const canvas = this.viewPort.canvas;
2271
2279
  if (!canvas)
2272
2280
  throw Error("canvas is null");
@@ -2275,47 +2283,48 @@ class Controller {
2275
2283
  if (this._pointButtonIsDown.size > 0)
2276
2284
  return;
2277
2285
  const hits = this.getHitResultUnderCursor();
2278
- const component = hits === null || hits === void 0 ? void 0 : hits.component;
2286
+ const component = (_a = hits === null || hits === void 0 ? void 0 : hits.component) !== null && _a !== void 0 ? _a : null;
2287
+ const actor = (_b = component === null || component === void 0 ? void 0 : component.parentActor) !== null && _b !== void 0 ? _b : null;
2288
+ // Component 级别 hover 检测
2279
2289
  if (component !== this.hoveringComponent) {
2280
- this.clearHoveringComponent();
2281
- if (component instanceof SceneComponent && component.isHoverEnabled && hits) {
2282
- this.fireHoverEvent(component, hits.hit, true);
2290
+ if (this.hoveringComponent) {
2291
+ this.fireComponentHoverEnd(this.hoveringComponent);
2292
+ }
2293
+ if (component && component.isHoverEnabled && hits) {
2294
+ this.fireComponentHoverBegin(component, hits.hit);
2295
+ }
2296
+ }
2297
+ // Actor 级别 hover 检测(独立于 Component)
2298
+ if (actor !== this.hoveringActor) {
2299
+ if (this.hoveringActor && this.hoveringComponent) {
2300
+ this.fireActorHoverEnd(this.hoveringActor, this.hoveringComponent);
2301
+ }
2302
+ if (actor && component && actor.isHoverEnabled && hits) {
2303
+ this.fireActorHoverBegin(actor, component, hits.hit);
2283
2304
  }
2284
2305
  }
2306
+ this.hoveringComponent = component;
2307
+ this.hoveringActor = actor;
2285
2308
  }
2286
- clearHoveringComponent() {
2309
+ clearHovering() {
2287
2310
  if (this.hoveringComponent) {
2288
- this.fireHoverEvent(this.hoveringComponent, null, false);
2311
+ this.fireComponentHoverEnd(this.hoveringComponent);
2289
2312
  }
2290
- }
2291
- fireHoverEvent(component, hit, isBegin) {
2292
- const event = { component, hit, handled: false };
2293
- if (isBegin) {
2294
- this._onComponentHoverBeginDelegate.broadcast(event);
2295
- if (!event.handled) {
2296
- component.onHorveringBegin();
2297
- }
2298
- this.hoveringComponent = component;
2299
- }
2300
- else {
2301
- this._onComponentHoverEndDelegate.broadcast(event);
2302
- if (!event.handled) {
2303
- component.onHorveringEnd();
2304
- }
2305
- this.hoveringComponent = null;
2313
+ if (this.hoveringActor && this.hoveringComponent) {
2314
+ this.fireActorHoverEnd(this.hoveringActor, this.hoveringComponent);
2306
2315
  }
2316
+ this.hoveringComponent = null;
2317
+ this.hoveringActor = null;
2307
2318
  }
2308
2319
  onPointerUpEvent(event) {
2309
2320
  this._pointButtonIsDown.delete(event.button);
2310
2321
  if (event.button !== 0)
2311
2322
  return;
2312
- // Check if pointer moved too much (drag instead of click)
2313
2323
  const pointerOffset = this._tempVec2.subVectors(this.pointerLeftDownPosition, this.pointerPosition).length();
2314
2324
  if (pointerOffset > 0.005) {
2315
2325
  this.clearClickTimer();
2316
2326
  return;
2317
2327
  }
2318
- // 保存修饰键状态
2319
2328
  this.prepareClickModifiers = {
2320
2329
  ctrlKey: event.ctrlKey,
2321
2330
  shiftKey: event.shiftKey,
@@ -2337,7 +2346,7 @@ class Controller {
2337
2346
  this.leftClickTimer = window.setTimeout(() => {
2338
2347
  this.leftClickTimer = null;
2339
2348
  if (this.prepareClickComponent && this.prepareClickHit) {
2340
- this.fireClickEvent(this.prepareClickComponent, this.prepareClickHit, false, this.prepareClickModifiers);
2349
+ this.fireClickEvents(this.prepareClickComponent, this.prepareClickHit, false);
2341
2350
  this.prepareClickComponent = null;
2342
2351
  this.prepareClickHit = null;
2343
2352
  }
@@ -2350,7 +2359,7 @@ class Controller {
2350
2359
  handleDoubleClick() {
2351
2360
  this.clearClickTimer();
2352
2361
  if (this.prepareClickComponent && this.prepareClickHit) {
2353
- this.fireClickEvent(this.prepareClickComponent, this.prepareClickHit, true, this.prepareClickModifiers);
2362
+ this.fireClickEvents(this.prepareClickComponent, this.prepareClickHit, true);
2354
2363
  }
2355
2364
  else {
2356
2365
  this._onClickNothingDelegate.broadcast();
@@ -2358,8 +2367,40 @@ class Controller {
2358
2367
  this.prepareClickComponent = null;
2359
2368
  this.prepareClickHit = null;
2360
2369
  }
2361
- fireClickEvent(component, hit, isDoubleClick, modifiers) {
2362
- const event = Object.assign({ component, hit, handled: false }, modifiers);
2370
+ onPointerDownEvent(event) {
2371
+ this._pointButtonIsDown.add(event.button);
2372
+ if (event.button === 0) {
2373
+ this.pointerLeftDownPosition.copy(this.pointerPosition);
2374
+ }
2375
+ const hit = this.getHitResultUnderCursor();
2376
+ const component = hit === null || hit === void 0 ? void 0 : hit.component;
2377
+ if (component instanceof SceneComponent && hit) {
2378
+ this.firePointerDownEvent(component, hit.hit, event.button);
2379
+ }
2380
+ }
2381
+ onPointerEnterEvent(_event) {
2382
+ this.addCorePointerListeners();
2383
+ }
2384
+ onPointerLeaveEvent(_event) {
2385
+ this.removeCorePointerListeners();
2386
+ }
2387
+ // ==================== Component Level Events ====================
2388
+ fireComponentHoverBegin(component, hit) {
2389
+ const event = { component, hit, handled: false };
2390
+ this._onComponentHoverBeginDelegate.broadcast(event);
2391
+ if (!event.handled) {
2392
+ component.onHorveringBegin();
2393
+ }
2394
+ }
2395
+ fireComponentHoverEnd(component) {
2396
+ const event = { component, hit: null, handled: false };
2397
+ this._onComponentHoverEndDelegate.broadcast(event);
2398
+ if (!event.handled) {
2399
+ component.onHorveringEnd();
2400
+ }
2401
+ }
2402
+ fireComponentClick(component, hit, isDoubleClick) {
2403
+ const event = Object.assign({ component, hit, handled: false }, this.prepareClickModifiers);
2363
2404
  if (isDoubleClick) {
2364
2405
  this._onComponentDoubleClickDelegate.broadcast(event);
2365
2406
  if (!event.handled) {
@@ -2373,33 +2414,56 @@ class Controller {
2373
2414
  }
2374
2415
  }
2375
2416
  }
2376
- clearClickTimer() {
2377
- if (this.leftClickTimer) {
2378
- window.clearTimeout(this.leftClickTimer);
2379
- this.leftClickTimer = null;
2380
- }
2417
+ firePointerDownEvent(component, hit, button) {
2418
+ const event = { component, hit, button, handled: false };
2419
+ this._onComponentPointerDownDelegate.broadcast(event);
2381
2420
  }
2382
- onPointerDownEvent(event) {
2383
- this._pointButtonIsDown.add(event.button);
2384
- if (event.button === 0) {
2385
- this.pointerLeftDownPosition.copy(this.pointerPosition);
2421
+ // ==================== Actor Level Events ====================
2422
+ fireActorHoverBegin(actor, component, hit) {
2423
+ const event = { actor, component, hit, handled: false };
2424
+ this._onActorHoverBeginDelegate.broadcast(event);
2425
+ if (!event.handled) {
2426
+ actor.onActorHoverBegin(component);
2386
2427
  }
2387
- // 广播组件按下事件
2388
- const hit = this.getHitResultUnderCursor();
2389
- const component = hit === null || hit === void 0 ? void 0 : hit.component;
2390
- if (component instanceof SceneComponent && hit) {
2391
- this.firePointerDownEvent(component, hit.hit, event.button);
2428
+ }
2429
+ fireActorHoverEnd(actor, component) {
2430
+ const event = { actor, component, hit: null, handled: false };
2431
+ this._onActorHoverEndDelegate.broadcast(event);
2432
+ if (!event.handled) {
2433
+ actor.onActorHoverEnd(component);
2392
2434
  }
2393
2435
  }
2394
- firePointerDownEvent(component, hit, button) {
2395
- const event = { component, hit, button, handled: false };
2396
- this._onComponentPointerDownDelegate.broadcast(event);
2436
+ fireActorClick(actor, component, hit, isDoubleClick) {
2437
+ const event = Object.assign({ actor, component, hit, handled: false }, this.prepareClickModifiers);
2438
+ if (isDoubleClick) {
2439
+ this._onActorDoubleClickDelegate.broadcast(event);
2440
+ if (!event.handled) {
2441
+ actor.onActorDoubleClick(component);
2442
+ }
2443
+ }
2444
+ else {
2445
+ this._onActorClickDelegate.broadcast(event);
2446
+ if (!event.handled) {
2447
+ actor.onActorClick(component);
2448
+ }
2449
+ }
2397
2450
  }
2398
- onPointerEnterEvent(_event) {
2399
- this.addCorePointerListeners();
2451
+ // ==================== Combined Events ====================
2452
+ fireClickEvents(component, hit, isDoubleClick) {
2453
+ // Component level
2454
+ this.fireComponentClick(component, hit, isDoubleClick);
2455
+ // Actor level
2456
+ const actor = component.parentActor;
2457
+ if (actor && actor.isClickEnabled) {
2458
+ this.fireActorClick(actor, component, hit, isDoubleClick);
2459
+ }
2400
2460
  }
2401
- onPointerLeaveEvent(_event) {
2402
- this.removeCorePointerListeners();
2461
+ // ==================== Utility ====================
2462
+ clearClickTimer() {
2463
+ if (this.leftClickTimer) {
2464
+ window.clearTimeout(this.leftClickTimer);
2465
+ this.leftClickTimer = null;
2466
+ }
2403
2467
  }
2404
2468
  addCorePointerListeners() {
2405
2469
  const canvas = this.viewPort.canvas;
@@ -2435,17 +2499,14 @@ class Controller {
2435
2499
  this._raycastVec2.set(x, y);
2436
2500
  this.raycaster.setFromCamera(this._raycastVec2, this.camera);
2437
2501
  const hits = this.raycaster.intersectObjects(this.world.scene.children, true);
2438
- let out = [];
2502
+ const out = [];
2439
2503
  for (const hit of hits) {
2440
2504
  if (hit.object.userData["rayIgnored"])
2441
2505
  continue;
2442
2506
  const component = hit.object.userData["LYObject"];
2443
2507
  if (!component)
2444
2508
  continue;
2445
- out.push({
2446
- component: component,
2447
- hit: hit
2448
- });
2509
+ out.push({ component, hit });
2449
2510
  }
2450
2511
  return out;
2451
2512
  }
@@ -2638,15 +2699,21 @@ class Actor extends BaseObject {
2638
2699
  this.app.world.removeTickableActor(this);
2639
2700
  }
2640
2701
  }
2702
+ // Delegate getters
2703
+ get onHoverBeginDelegate() { return this._onHoverBeginDelegate; }
2704
+ get onHoverEndDelegate() { return this._onHoverEndDelegate; }
2705
+ get onClickDelegate() { return this._onClickDelegate; }
2706
+ get onDoubleClickDelegate() { return this._onDoubleClickDelegate; }
2641
2707
  constructor(app, uuid) {
2642
2708
  super(uuid);
2643
2709
  this._name = "Actor";
2644
2710
  this._rootComponent = null;
2645
2711
  this._world = null;
2646
- this.onClickedEvent = [];
2647
- this.onDoubleClickedEvent = [];
2648
- this.onHoverBeginEvent = [];
2649
- this.onHoverEndEvent = [];
2712
+ // Actor 级别事件 Delegates
2713
+ this._onHoverBeginDelegate = new Delegate();
2714
+ this._onHoverEndDelegate = new Delegate();
2715
+ this._onClickDelegate = new Delegate();
2716
+ this._onDoubleClickDelegate = new Delegate();
2650
2717
  this.app = app;
2651
2718
  this.rootComponent = this.constructRootComponent();
2652
2719
  this.rootComponent.parentActor = this;
@@ -2901,80 +2968,18 @@ class Actor extends BaseObject {
2901
2968
  set isClickEnabled(bCanHorver) {
2902
2969
  this.rootComponent.isClickEnabled = bCanHorver;
2903
2970
  }
2904
- // hovering begin
2905
- addHoveringBeginEvent(newFunc) {
2906
- this.onHoverBeginEvent.push(newFunc);
2907
- }
2908
- removeHoveringBeginEvent(target) {
2909
- let index = this.onHoverBeginEvent.indexOf(target);
2910
- if (index >= 0) {
2911
- this.onHoverBeginEvent.splice(index, 1);
2912
- }
2913
- }
2914
- clearHoveringBeginEvent() {
2915
- this.onHoverBeginEvent = [];
2916
- }
2917
- onComponentHorveringBegin(component) {
2918
- for (let i = 0; i < this.onHoverBeginEvent.length; ++i) {
2919
- this.onHoverBeginEvent[i](component);
2920
- }
2921
- }
2922
- // hovering end
2923
- addHoveringEndEvent(newFunc) {
2924
- this.onHoverEndEvent.push(newFunc);
2925
- }
2926
- removeHoveringEndEvent(target) {
2927
- let index = this.onHoverEndEvent.indexOf(target);
2928
- if (index >= 0) {
2929
- this.onHoverEndEvent.splice(index, 1);
2930
- }
2931
- }
2932
- clearHoveringEndEvent() {
2933
- this.onHoverEndEvent = [];
2934
- }
2935
- onComponentHorveringEnd(component) {
2936
- // console.log("onComponentHorveringEnd", this)
2937
- for (let i = 0; i < this.onHoverEndEvent.length; ++i) {
2938
- this.onHoverEndEvent[i](component);
2939
- }
2940
- }
2941
- //click
2942
- addClickEvent(newFunc) {
2943
- this.onClickedEvent.push(newFunc);
2944
- }
2945
- removeClickEvent(target) {
2946
- let index = this.onClickedEvent.indexOf(target);
2947
- if (index >= 0) {
2948
- this.onClickedEvent.splice(index, 1);
2949
- }
2950
- }
2951
- clearClickEvent() {
2952
- this.onClickedEvent = [];
2971
+ // ==================== Actor Events ====================
2972
+ onActorHoverBegin(component) {
2973
+ this._onHoverBeginDelegate.broadcast(component);
2953
2974
  }
2954
- onComponentClicked(component) {
2955
- //console.log("onComponentClicked", this.Name, component)
2956
- for (let i = 0; i < this.onClickedEvent.length; ++i) {
2957
- this.onClickedEvent[i](component);
2958
- }
2975
+ onActorHoverEnd(component) {
2976
+ this._onHoverEndDelegate.broadcast(component);
2959
2977
  }
2960
- // double click
2961
- addDoubleClickEvent(newFunc) {
2962
- this.onDoubleClickedEvent.push(newFunc);
2963
- }
2964
- removeDoubleClickEvent(target) {
2965
- let index = this.onClickedEvent.indexOf(target);
2966
- if (index >= 0) {
2967
- this.onDoubleClickedEvent.splice(index, 1);
2968
- }
2969
- }
2970
- onComponentDoubleClicked(component) {
2971
- //console.log("onComponentClicked", this.Name, component)
2972
- for (let i = 0; i < this.onDoubleClickedEvent.length; ++i) {
2973
- this.onDoubleClickedEvent[i](component);
2974
- }
2978
+ onActorClick(component) {
2979
+ this._onClickDelegate.broadcast(component);
2975
2980
  }
2976
- clearDoubleClickEvent() {
2977
- this.onDoubleClickedEvent = [];
2981
+ onActorDoubleClick(component) {
2982
+ this._onDoubleClickDelegate.broadcast(component);
2978
2983
  }
2979
2984
  }
2980
2985
 
package/dist/index.d.ts CHANGED
@@ -10,6 +10,7 @@ export { AttachmentRules } from "./lythreeframe/Defines";
10
10
  export { Delegate } from "./lythreeframe/Delegate";
11
11
  export { ThreeJsApp } from "./lythreeframe/ThreeJsApp";
12
12
  export { Controller } from "./lythreeframe/Frame/Controller";
13
+ export type { HitResult, ComponentInteractionEvent, ComponentHoverEvent, ComponentPointerDownEvent, ActorInteractionEvent, ActorHoverEvent } from "./lythreeframe/Frame/Controller";
13
14
  export { Viewport } from "./lythreeframe/Frame/Viewport";
14
15
  export { World } from "./lythreeframe/Frame/World";
15
16
  export type { CameraParam, PerspectiveCameraParam, OrthographicCameraParam } from './lythreeframe/Frame/Parameters/CameraParameter';
@@ -4,29 +4,25 @@ import { World } from "./World";
4
4
  import { Viewport } from "./Viewport";
5
5
  import { Pawn } from "../Object/PawnV2/Pawn";
6
6
  import { SceneComponent } from "../Object/Components/SceneComponent";
7
+ import { Actor } from "../Object/Actor";
7
8
  import { Delegate } from "../Delegate";
8
9
  export interface HitResult {
9
10
  component: SceneComponent;
10
11
  hit: Intersection;
11
12
  }
12
- /** 组件交互事件基类 */
13
+ /** 组件交互事件 */
13
14
  export interface ComponentInteractionEvent {
14
15
  component: SceneComponent;
15
16
  hit: Intersection;
16
- /** 设置为 true 阻止组件自身的回调被调用 */
17
17
  handled: boolean;
18
- /** 点击时是否按下 Ctrl 键 */
19
18
  ctrlKey: boolean;
20
- /** 点击时是否按下 Shift 键 */
21
19
  shiftKey: boolean;
22
- /** 点击时是否按下 Alt 键 */
23
20
  altKey: boolean;
24
21
  }
25
22
  /** 组件悬停事件 */
26
23
  export interface ComponentHoverEvent {
27
24
  component: SceneComponent;
28
25
  hit: Intersection | null;
29
- /** 设置为 true 阻止组件自身的 onHoveringBegin/End 被调用 */
30
26
  handled: boolean;
31
27
  }
32
28
  /** 组件按下事件 */
@@ -34,13 +30,31 @@ export interface ComponentPointerDownEvent {
34
30
  component: SceneComponent;
35
31
  hit: Intersection;
36
32
  button: number;
37
- /** 设置为 true 阻止默认处理 */
33
+ handled: boolean;
34
+ }
35
+ /** Actor 交互事件 */
36
+ export interface ActorInteractionEvent {
37
+ actor: Actor;
38
+ component: SceneComponent;
39
+ hit: Intersection;
40
+ handled: boolean;
41
+ ctrlKey: boolean;
42
+ shiftKey: boolean;
43
+ altKey: boolean;
44
+ }
45
+ /** Actor 悬停事件 */
46
+ export interface ActorHoverEvent {
47
+ actor: Actor;
48
+ component: SceneComponent;
49
+ hit: Intersection | null;
38
50
  handled: boolean;
39
51
  }
40
52
  export declare class Controller {
41
53
  protected _app: ThreeJsApp;
42
54
  protected _pawn: Pawn | null;
43
55
  protected raycaster: Raycaster;
56
+ protected hoveringComponent: SceneComponent | null;
57
+ protected hoveringActor: Actor | null;
44
58
  protected prepareClickComponent: SceneComponent | null;
45
59
  protected prepareClickHit: Intersection | null;
46
60
  protected prepareClickModifiers: {
@@ -48,14 +62,17 @@ export declare class Controller {
48
62
  shiftKey: boolean;
49
63
  altKey: boolean;
50
64
  };
51
- protected hoveringComponent: SceneComponent | null;
52
65
  protected _pointButtonIsDown: Set<number>;
53
- protected _onClickNothingDelegate: Delegate<[void]>;
54
66
  protected _onComponentClickDelegate: Delegate<[ComponentInteractionEvent]>;
55
67
  protected _onComponentDoubleClickDelegate: Delegate<[ComponentInteractionEvent]>;
56
68
  protected _onComponentHoverBeginDelegate: Delegate<[ComponentHoverEvent]>;
57
69
  protected _onComponentHoverEndDelegate: Delegate<[ComponentHoverEvent]>;
58
70
  protected _onComponentPointerDownDelegate: Delegate<[ComponentPointerDownEvent]>;
71
+ protected _onActorClickDelegate: Delegate<[ActorInteractionEvent]>;
72
+ protected _onActorDoubleClickDelegate: Delegate<[ActorInteractionEvent]>;
73
+ protected _onActorHoverBeginDelegate: Delegate<[ActorHoverEvent]>;
74
+ protected _onActorHoverEndDelegate: Delegate<[ActorHoverEvent]>;
75
+ protected _onClickNothingDelegate: Delegate<[void]>;
59
76
  protected pointerPosition: Vector2;
60
77
  protected pointerLeftDownPosition: Vector2;
61
78
  protected readonly _tempVec2: Vector2;
@@ -71,34 +88,39 @@ export declare class Controller {
71
88
  get world(): World;
72
89
  get viewPort(): Viewport;
73
90
  get app(): ThreeJsApp;
74
- get onClickNothingDelegate(): Delegate<[void]>;
91
+ get pawn(): Pawn;
75
92
  get onComponentClickDelegate(): Delegate<[ComponentInteractionEvent]>;
76
93
  get onComponentDoubleClickDelegate(): Delegate<[ComponentInteractionEvent]>;
77
94
  get onComponentHoverBeginDelegate(): Delegate<[ComponentHoverEvent]>;
78
95
  get onComponentHoverEndDelegate(): Delegate<[ComponentHoverEvent]>;
79
96
  get onComponentPointerDownDelegate(): Delegate<[ComponentPointerDownEvent]>;
80
- get pawn(): Pawn;
97
+ get onActorClickDelegate(): Delegate<[ActorInteractionEvent]>;
98
+ get onActorDoubleClickDelegate(): Delegate<[ActorInteractionEvent]>;
99
+ get onActorHoverBeginDelegate(): Delegate<[ActorHoverEvent]>;
100
+ get onActorHoverEndDelegate(): Delegate<[ActorHoverEvent]>;
101
+ get onClickNothingDelegate(): Delegate<[void]>;
81
102
  constructor(app: ThreeJsApp);
82
103
  init(): void;
83
104
  updateCamera(): void;
84
105
  tick(deltaTime: number): void;
85
106
  destroy(): void;
86
107
  protected onPointerMoveEvent(event: MouseEvent): void;
87
- protected clearHoveringComponent(): void;
88
- protected fireHoverEvent(component: SceneComponent, hit: Intersection | null, isBegin: boolean): void;
108
+ protected clearHovering(): void;
89
109
  protected onPointerUpEvent(event: MouseEvent): void;
90
110
  protected handleFirstClick(): void;
91
111
  protected handleDoubleClick(): void;
92
- protected fireClickEvent(component: SceneComponent, hit: Intersection, isDoubleClick: boolean, modifiers: {
93
- ctrlKey: boolean;
94
- shiftKey: boolean;
95
- altKey: boolean;
96
- }): void;
97
- protected clearClickTimer(): void;
98
112
  protected onPointerDownEvent(event: MouseEvent): void;
99
- protected firePointerDownEvent(component: SceneComponent, hit: Intersection, button: number): void;
100
113
  protected onPointerEnterEvent(_event: MouseEvent): void;
101
114
  protected onPointerLeaveEvent(_event: MouseEvent): void;
115
+ protected fireComponentHoverBegin(component: SceneComponent, hit: Intersection): void;
116
+ protected fireComponentHoverEnd(component: SceneComponent): void;
117
+ protected fireComponentClick(component: SceneComponent, hit: Intersection, isDoubleClick: boolean): void;
118
+ protected firePointerDownEvent(component: SceneComponent, hit: Intersection, button: number): void;
119
+ protected fireActorHoverBegin(actor: Actor, component: SceneComponent, hit: Intersection): void;
120
+ protected fireActorHoverEnd(actor: Actor, component: SceneComponent): void;
121
+ protected fireActorClick(actor: Actor, component: SceneComponent, hit: Intersection, isDoubleClick: boolean): void;
122
+ protected fireClickEvents(component: SceneComponent, hit: Intersection, isDoubleClick: boolean): void;
123
+ protected clearClickTimer(): void;
102
124
  protected addCorePointerListeners(): void;
103
125
  protected removeCorePointerListeners(): void;
104
126
  getHitResultUnderCursor(): HitResult | null;
@@ -4,6 +4,7 @@ import { BaseObject } from "./BaseObject";
4
4
  import { World } from "../Frame/World";
5
5
  import { ThreeJsApp } from "../ThreeJsApp";
6
6
  import { SceneComponent } from "./Components/SceneComponent";
7
+ import { Delegate } from "../Delegate";
7
8
  export declare class Actor extends BaseObject {
8
9
  get world(): World | null;
9
10
  get name(): string;
@@ -20,10 +21,14 @@ export declare class Actor extends BaseObject {
20
21
  protected _rootComponent: SceneComponent | null;
21
22
  protected _world: World | null;
22
23
  protected app: ThreeJsApp;
23
- protected onClickedEvent: ((component?: SceneComponent) => void)[];
24
- protected onDoubleClickedEvent: ((component?: SceneComponent) => void)[];
25
- protected onHoverBeginEvent: ((component?: SceneComponent) => void)[];
26
- protected onHoverEndEvent: ((component?: SceneComponent) => void)[];
24
+ protected _onHoverBeginDelegate: Delegate<[SceneComponent]>;
25
+ protected _onHoverEndDelegate: Delegate<[SceneComponent]>;
26
+ protected _onClickDelegate: Delegate<[SceneComponent]>;
27
+ protected _onDoubleClickDelegate: Delegate<[SceneComponent]>;
28
+ get onHoverBeginDelegate(): Delegate<[SceneComponent]>;
29
+ get onHoverEndDelegate(): Delegate<[SceneComponent]>;
30
+ get onClickDelegate(): Delegate<[SceneComponent]>;
31
+ get onDoubleClickDelegate(): Delegate<[SceneComponent]>;
27
32
  constructor(app: ThreeJsApp, uuid?: string);
28
33
  protected constructRootComponent(): SceneComponent;
29
34
  getBoundsCenterPosition(bInWorldSpace?: boolean): Vector3;
@@ -73,20 +78,8 @@ export declare class Actor extends BaseObject {
73
78
  set isHoverEnabled(bCanHorver: boolean);
74
79
  get isClickEnabled(): boolean;
75
80
  set isClickEnabled(bCanHorver: boolean);
76
- addHoveringBeginEvent(newFunc: (component?: SceneComponent) => void): void;
77
- removeHoveringBeginEvent(target: (component?: SceneComponent) => void): void;
78
- clearHoveringBeginEvent(): void;
79
- onComponentHorveringBegin(component: SceneComponent): void;
80
- addHoveringEndEvent(newFunc: (component?: SceneComponent) => void): void;
81
- removeHoveringEndEvent(target: (component?: SceneComponent) => void): void;
82
- clearHoveringEndEvent(): void;
83
- onComponentHorveringEnd(component: SceneComponent): void;
84
- addClickEvent(newFunc: (component?: SceneComponent) => void): void;
85
- removeClickEvent(target: (component?: SceneComponent) => void): void;
86
- clearClickEvent(): void;
87
- onComponentClicked(component: SceneComponent): void;
88
- addDoubleClickEvent(newFunc: (component?: SceneComponent) => void): void;
89
- removeDoubleClickEvent(target: (component?: SceneComponent) => void): void;
90
- onComponentDoubleClicked(component: SceneComponent): void;
91
- clearDoubleClickEvent(): void;
81
+ onActorHoverBegin(component: SceneComponent): void;
82
+ onActorHoverEnd(component: SceneComponent): void;
83
+ onActorClick(component: SceneComponent): void;
84
+ onActorDoubleClick(component: SceneComponent): void;
92
85
  }
@@ -4,11 +4,20 @@ import { Component } from "./Component";
4
4
  import { World } from "../../Frame/World";
5
5
  import { AttachmentRules } from "../../Defines";
6
6
  import { ThreeJsApp } from "../../ThreeJsApp";
7
+ import { Delegate } from "../../Delegate";
7
8
  export declare class SceneComponent extends Component {
8
9
  set parentActor(value: Actor | null);
9
10
  get parentActor(): Actor | null;
10
11
  protected bCanHover: boolean;
11
12
  protected bCanClick: boolean;
13
+ protected _onHoverBeginDelegate: Delegate<[void]>;
14
+ protected _onHoverEndDelegate: Delegate<[void]>;
15
+ protected _onClickDelegate: Delegate<[void]>;
16
+ protected _onDoubleClickDelegate: Delegate<[void]>;
17
+ get onHoverBeginDelegate(): Delegate<[void]>;
18
+ get onHoverEndDelegate(): Delegate<[void]>;
19
+ get onClickDelegate(): Delegate<[void]>;
20
+ get onDoubleClickDelegate(): Delegate<[void]>;
12
21
  get world(): World;
13
22
  protected app: ThreeJsApp;
14
23
  constructor(app: ThreeJsApp, uuid?: string);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lythreeframe",
3
- "version": "1.2.62",
3
+ "version": "1.2.63",
4
4
  "description": "Three.js 封装",
5
5
  "main": "dist/bundle.cjs.js",
6
6
  "module": "dist/bundle.esm.js",