@fps-games/editor 0.1.4-beta.2 → 0.1.4-beta.3

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 (38) hide show
  1. package/dist/local-editor-harness.js +1 -2
  2. package/dist/local-editor-harness.js.map +1 -1
  3. package/dist/playable-babylon-facade.d.ts +1 -1
  4. package/dist/playable-babylon-facade.d.ts.map +1 -1
  5. package/dist/playable-babylon-facade.js.map +1 -1
  6. package/dist/playable-babylon-rendering.d.ts +57 -1
  7. package/dist/playable-babylon-rendering.d.ts.map +1 -1
  8. package/dist/playable-babylon-rendering.js +211 -9
  9. package/dist/playable-babylon-rendering.js.map +1 -1
  10. package/dist/playable-local-editor-host.d.ts +2 -0
  11. package/dist/playable-local-editor-host.d.ts.map +1 -1
  12. package/dist/playable-local-editor-host.js +5 -2
  13. package/dist/playable-local-editor-host.js.map +1 -1
  14. package/dist/playable-sdk.d.ts +4 -3
  15. package/dist/playable-sdk.d.ts.map +1 -1
  16. package/dist/playable-sdk.js +1 -1
  17. package/dist/playable-sdk.js.map +1 -1
  18. package/node_modules/@fps-games/babylon-renderer/dist/shadows/planar-shadow-system.js +2 -0
  19. package/node_modules/@fps-games/babylon-renderer/dist/shadows/planar-shadow-system.js.map +1 -1
  20. package/node_modules/@fps-games/babylon-renderer/package.json +1 -1
  21. package/node_modules/@fps-games/editor-babylon/dist/scene-view-camera-controller.js +2 -2
  22. package/node_modules/@fps-games/editor-babylon/package.json +5 -5
  23. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-panels.d.ts.map +1 -1
  24. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-panels.js +36 -3
  25. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-panels.js.map +1 -1
  26. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui.d.ts.map +1 -1
  27. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui.js +148 -0
  28. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui.js.map +1 -1
  29. package/node_modules/@fps-games/editor-browser/package.json +3 -3
  30. package/node_modules/@fps-games/editor-core/package.json +2 -2
  31. package/node_modules/@fps-games/editor-forge-play/dist/agent-transport.d.ts +25 -0
  32. package/node_modules/@fps-games/editor-forge-play/dist/agent-transport.d.ts.map +1 -1
  33. package/node_modules/@fps-games/editor-forge-play/dist/agent-transport.js +56 -9
  34. package/node_modules/@fps-games/editor-forge-play/dist/agent-transport.js.map +1 -1
  35. package/node_modules/@fps-games/editor-forge-play/package.json +2 -2
  36. package/node_modules/@fps-games/editor-playable-sdk/package.json +3 -3
  37. package/node_modules/@fps-games/editor-protocol/package.json +1 -1
  38. package/package.json +8 -8
@@ -342,6 +342,67 @@ function readInspectorCommitMode(input) {
342
342
  function readRenderingCommitMode(input) {
343
343
  return input.dataset.renderingCommitMode ?? 'live';
344
344
  }
345
+ function resolveLocalEditorRightDockContentKey(state, tab, inspectorFilter) {
346
+ if (tab === 'rendering') {
347
+ const rendering = state.renderingPanel;
348
+ if (!rendering)
349
+ return 'rendering:none';
350
+ return [
351
+ 'rendering',
352
+ rendering.sections.map(section => [
353
+ section.id,
354
+ section.systems.map(system => [
355
+ system.id,
356
+ system.properties.map(property => property.path).join(','),
357
+ ].join(':')).join('|'),
358
+ ].join('=')).join(';'),
359
+ ].join(':');
360
+ }
361
+ const selectionCount = state.selectionSummary?.count ?? state.selectedIds.length;
362
+ return [
363
+ 'inspector',
364
+ selectionCount,
365
+ state.selectionSummary?.activeId ?? state.activeId ?? '',
366
+ state.selectedIds.join(','),
367
+ inspectorFilter,
368
+ ].join(':');
369
+ }
370
+ function findLocalEditorRightDockScrollViewport(tab, inspectorPanel, renderingPanel) {
371
+ const panel = tab === 'inspector' ? inspectorPanel : renderingPanel;
372
+ const selector = tab === 'inspector'
373
+ ? '[data-editor-inspector-scroll-viewport]'
374
+ : '[data-editor-rendering-scroll-viewport]';
375
+ return panel.querySelector(selector) ?? panel;
376
+ }
377
+ function captureLocalEditorRightDockScrollSnapshot(state, tab, inspectorFilter, inspectorPanel, renderingPanel) {
378
+ if (!state || state.mode !== 'editor')
379
+ return null;
380
+ const viewport = findLocalEditorRightDockScrollViewport(tab, inspectorPanel, renderingPanel);
381
+ if (!viewport)
382
+ return null;
383
+ const panel = tab === 'inspector' ? inspectorPanel : renderingPanel;
384
+ return {
385
+ tab,
386
+ contentKey: resolveLocalEditorRightDockContentKey(state, tab, inspectorFilter),
387
+ panelId: panel.dataset.editorPanelId ?? tab,
388
+ scrollLeft: viewport.scrollLeft,
389
+ scrollTop: viewport.scrollTop,
390
+ };
391
+ }
392
+ function restoreLocalEditorRightDockScrollSnapshot(snapshot, state, tab, inspectorFilter, inspectorPanel, renderingPanel) {
393
+ if (!snapshot || snapshot.tab !== tab || state.mode !== 'editor')
394
+ return;
395
+ const panel = tab === 'inspector' ? inspectorPanel : renderingPanel;
396
+ if ((panel.dataset.editorPanelId ?? tab) !== snapshot.panelId)
397
+ return;
398
+ if (resolveLocalEditorRightDockContentKey(state, tab, inspectorFilter) !== snapshot.contentKey)
399
+ return;
400
+ const viewport = findLocalEditorRightDockScrollViewport(tab, inspectorPanel, renderingPanel);
401
+ if (!viewport)
402
+ return;
403
+ viewport.scrollLeft = snapshot.scrollLeft;
404
+ viewport.scrollTop = snapshot.scrollTop;
405
+ }
345
406
  function readInspectorImmediateSource(input) {
346
407
  if (input instanceof HTMLSelectElement)
347
408
  return 'select';
@@ -365,6 +426,49 @@ function readRenderingImmediateSource(input) {
365
426
  return 'list';
366
427
  return 'input';
367
428
  }
429
+ function markLocalEditorKeyboardCommittedValue(input) {
430
+ input.dataset.editorKeyboardCommittedValue = input.value;
431
+ }
432
+ function consumeLocalEditorKeyboardCommittedValue(input) {
433
+ const committedValue = input.dataset.editorKeyboardCommittedValue;
434
+ if (committedValue == null || committedValue !== input.value)
435
+ return false;
436
+ delete input.dataset.editorKeyboardCommittedValue;
437
+ return true;
438
+ }
439
+ function isLocalEditorKeyboardCommitEvent(event, input) {
440
+ if (event.key !== 'Enter' || event.isComposing)
441
+ return false;
442
+ if (input instanceof HTMLTextAreaElement)
443
+ return event.metaKey || event.ctrlKey;
444
+ return input instanceof HTMLInputElement;
445
+ }
446
+ function commitLocalEditorInspectorInput(input, callbacks, lockedInspectorVectorGroups) {
447
+ if (!input.dataset.serializedPath || !input.dataset.serializedTargetId)
448
+ return false;
449
+ if (input.type === 'checkbox' || input.type === 'color')
450
+ return false;
451
+ const propertyInputs = createInspectorPropertyInputs(input, 'input', lockedInspectorVectorGroups);
452
+ if (!propertyInputs)
453
+ return false;
454
+ applyInspectorLockedVectorInputToDom(input, propertyInputs);
455
+ markLocalEditorKeyboardCommittedValue(input);
456
+ for (const propertyInput of propertyInputs)
457
+ callbacks.onPropertyInput?.(propertyInput);
458
+ return true;
459
+ }
460
+ function commitLocalEditorRenderingInput(input, callbacks) {
461
+ if (!input.dataset.editorRenderingProperty)
462
+ return false;
463
+ if (input instanceof HTMLInputElement && (input.type === 'checkbox' || input.type === 'color'))
464
+ return false;
465
+ const propertyInput = createRenderingPropertyInput(input, input instanceof HTMLTextAreaElement ? 'list' : 'input');
466
+ if (!propertyInput)
467
+ return false;
468
+ markLocalEditorKeyboardCommittedValue(input);
469
+ callbacks.onRenderingPropertyChange?.(propertyInput);
470
+ return true;
471
+ }
368
472
  export function captureLocalEditorEditableFocus(doc) {
369
473
  const active = doc.activeElement;
370
474
  if (!(active instanceof HTMLInputElement || active instanceof HTMLTextAreaElement || active instanceof HTMLSelectElement)) {
@@ -3247,6 +3351,16 @@ export function createLocalEditorBrowserUi(options = {}) {
3247
3351
  copyTextToClipboard(doc.defaultView, value);
3248
3352
  return;
3249
3353
  }
3354
+ const readonlyCopyButton = target?.closest('[data-editor-inspector-readonly-copy]');
3355
+ if (readonlyCopyButton) {
3356
+ const value = readonlyCopyButton.dataset.editorInspectorReadonlyCopyValue;
3357
+ if (!value)
3358
+ return;
3359
+ event.preventDefault();
3360
+ event.stopPropagation();
3361
+ copyTextToClipboard(doc.defaultView, value);
3362
+ return;
3363
+ }
3250
3364
  const materialSlotSelectTarget = target?.closest('[data-editor-inspector-material-slot-select]');
3251
3365
  const materialSlotSelectionId = materialSlotSelectTarget?.dataset.editorInspectorMaterialSlotSelect;
3252
3366
  if (materialSlotSelectionId) {
@@ -3292,6 +3406,8 @@ export function createLocalEditorBrowserUi(options = {}) {
3292
3406
  if (input instanceof HTMLInputElement && (input.type === 'text' || input.type === 'number')) {
3293
3407
  if (readInspectorCommitMode(input) !== 'change')
3294
3408
  return;
3409
+ if (consumeLocalEditorKeyboardCommittedValue(input))
3410
+ return;
3295
3411
  }
3296
3412
  const propertyInputs = createInspectorPropertyInputs(input, readInspectorImmediateSource(input), lockedInspectorVectorGroups);
3297
3413
  if (!propertyInputs)
@@ -3300,12 +3416,23 @@ export function createLocalEditorBrowserUi(options = {}) {
3300
3416
  for (const propertyInput of propertyInputs)
3301
3417
  callbacks.onPropertyInput?.(propertyInput);
3302
3418
  });
3419
+ inspectorPanel.addEventListener('keydown', (event) => {
3420
+ const input = event.target instanceof HTMLInputElement ? event.target : null;
3421
+ if (!input || !isLocalEditorKeyboardCommitEvent(event, input))
3422
+ return;
3423
+ if (!commitLocalEditorInspectorInput(input, callbacks, lockedInspectorVectorGroups))
3424
+ return;
3425
+ event.preventDefault();
3426
+ event.stopPropagation();
3427
+ });
3303
3428
  inspectorPanel.addEventListener('focusout', (event) => {
3304
3429
  const input = event.target instanceof HTMLInputElement ? event.target : null;
3305
3430
  if (!input?.dataset.serializedPath || !input.dataset.serializedTargetId)
3306
3431
  return;
3307
3432
  if (readInspectorCommitMode(input) !== 'blur')
3308
3433
  return;
3434
+ if (consumeLocalEditorKeyboardCommittedValue(input))
3435
+ return;
3309
3436
  const propertyInputs = createInspectorPropertyInputs(input, 'input', lockedInspectorVectorGroups);
3310
3437
  if (!propertyInputs)
3311
3438
  return;
@@ -3338,11 +3465,24 @@ export function createLocalEditorBrowserUi(options = {}) {
3338
3465
  if ((input instanceof HTMLInputElement && (input.type === 'text' || input.type === 'number')) || input instanceof HTMLTextAreaElement) {
3339
3466
  if (readRenderingCommitMode(input) !== 'change')
3340
3467
  return;
3468
+ if (consumeLocalEditorKeyboardCommittedValue(input))
3469
+ return;
3341
3470
  }
3342
3471
  const propertyInput = createRenderingPropertyInput(input, readRenderingImmediateSource(input));
3343
3472
  if (propertyInput)
3344
3473
  callbacks.onRenderingPropertyChange?.(propertyInput);
3345
3474
  });
3475
+ renderingPanel.addEventListener('keydown', (event) => {
3476
+ const input = event.target instanceof HTMLInputElement || event.target instanceof HTMLTextAreaElement
3477
+ ? event.target
3478
+ : null;
3479
+ if (!input || !isLocalEditorKeyboardCommitEvent(event, input))
3480
+ return;
3481
+ if (!commitLocalEditorRenderingInput(input, callbacks))
3482
+ return;
3483
+ event.preventDefault();
3484
+ event.stopPropagation();
3485
+ });
3346
3486
  renderingPanel.addEventListener('focusout', (event) => {
3347
3487
  const input = event.target instanceof HTMLInputElement || event.target instanceof HTMLTextAreaElement || event.target instanceof HTMLSelectElement
3348
3488
  ? event.target
@@ -3353,6 +3493,8 @@ export function createLocalEditorBrowserUi(options = {}) {
3353
3493
  return;
3354
3494
  if (readRenderingCommitMode(input) !== 'blur')
3355
3495
  return;
3496
+ if (consumeLocalEditorKeyboardCommittedValue(input))
3497
+ return;
3356
3498
  const propertyInput = createRenderingPropertyInput(input, input instanceof HTMLTextAreaElement ? 'list' : 'input');
3357
3499
  if (propertyInput)
3358
3500
  callbacks.onRenderingPropertyChange?.(propertyInput);
@@ -3557,13 +3699,18 @@ export function createLocalEditorBrowserUi(options = {}) {
3557
3699
  };
3558
3700
  renderPreviewState(currentState);
3559
3701
  if (shouldRenderInspectorPreview && panelRegistry.getRightDockTab() === 'inspector') {
3702
+ const rightDockScrollSnapshot = captureLocalEditorRightDockScrollSnapshot(currentState, 'inspector', inspectorFilter, inspectorPanel, renderingPanel);
3560
3703
  LocalEditorPanels.renderInspectorPanel(doc, inspectorPanel, currentState, inspectorFilter, {
3561
3704
  ...options.inspector,
3562
3705
  lockedVectorGroups: lockedInspectorVectorGroups,
3563
3706
  });
3707
+ restoreLocalEditorRightDockScrollSnapshot(rightDockScrollSnapshot, currentState, 'inspector', inspectorFilter, inspectorPanel, renderingPanel);
3564
3708
  }
3565
3709
  };
3566
3710
  const render = (state) => {
3711
+ const previousState = currentState;
3712
+ const previousRightTab = panelRegistry.getRightDockTab();
3713
+ const rightDockScrollSnapshot = captureLocalEditorRightDockScrollSnapshot(previousState, previousRightTab, inspectorFilter, inspectorPanel, renderingPanel);
3567
3714
  currentState = state;
3568
3715
  const focusSnapshot = captureLocalEditorEditableFocus(doc);
3569
3716
  const inEditor = state.mode === 'editor';
@@ -3760,6 +3907,7 @@ export function createLocalEditorBrowserUi(options = {}) {
3760
3907
  LocalEditorPanels.renderRenderingPanel(doc, renderingPanel, state);
3761
3908
  }
3762
3909
  restoreLocalEditorEditableFocus(doc, focusSnapshot);
3910
+ restoreLocalEditorRightDockScrollSnapshot(rightDockScrollSnapshot, state, activeRightTab, inspectorFilter, inspectorPanel, renderingPanel);
3763
3911
  };
3764
3912
  return {
3765
3913
  update(state) {