@babylonjs/inspector 9.2.1 → 9.3.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.
- package/bin/inspector-bridge.mjs +20 -2
- package/bin/inspector-cli.mjs +17 -2
- package/lib/cli/protocol.d.ts +24 -2
- package/lib/components/properties/postProcesses/postProcessProperties.d.ts +1 -1
- package/lib/{extensionsListService-CBQwBhYh.js → extensionsListService-DPHWDyzb.js} +2 -2
- package/lib/{extensionsListService-CBQwBhYh.js.map → extensionsListService-DPHWDyzb.js.map} +1 -1
- package/lib/{index-DmfAhsIm.js → index-BaFR1FRV.js} +278 -99
- package/lib/index-BaFR1FRV.js.map +1 -0
- package/lib/index.js +1 -1
- package/lib/inspectable.d.ts +5 -0
- package/lib/{quickCreateToolsService-C38aK2nP.js → quickCreateToolsService-DJ1GVvH-.js} +2 -2
- package/lib/{quickCreateToolsService-C38aK2nP.js.map → quickCreateToolsService-DJ1GVvH-.js.map} +1 -1
- package/lib/{reflectorService-Bs9E2OMh.js → reflectorService-Cd41l6Tr.js} +2 -2
- package/lib/{reflectorService-Bs9E2OMh.js.map → reflectorService-Cd41l6Tr.js.map} +1 -1
- package/lib/services/cli/cliConnectionStatus.d.ts +9 -3
- package/lib/services/cli/inspectableBridgeService.d.ts +6 -0
- package/lib/services/cli/inspectableCommandRegistry.d.ts +11 -0
- package/lib/services/panes/tools/import/gltfLoaderOptionsService.d.ts +3 -1
- package/package.json +1 -1
- package/lib/index-DmfAhsIm.js.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
2
|
import { createContext, forwardRef, useContext, useState, useCallback, Component, useMemo, useEffect, useRef, useReducer, Children, isValidElement, useLayoutEffect, useImperativeHandle, cloneElement, createElement, Suspense, memo, Fragment as Fragment$1, lazy } from 'react';
|
|
3
3
|
import { tokens, makeStyles, Tooltip as Tooltip$1, Button as Button$1, Spinner, Link as Link$1, Caption1, Body1, useFluent, Accordion as Accordion$1, AccordionHeader, Subtitle2Stronger, AccordionPanel, Divider, MessageBar as MessageBar$1, MessageBarBody, AccordionItem, SearchBox as SearchBox$1, Portal, ToggleButton as ToggleButton$1, InfoLabel as InfoLabel$1, Body1Strong, mergeClasses, useId, useToastController, Toast, ToastTitle, FluentProvider, Toaster, Checkbox as Checkbox$1, createLightTheme, createDarkTheme, TeachingPopover, TeachingPopoverSurface, TeachingPopoverHeader, TeachingPopoverBody, createDOMRenderer, RendererProvider, Menu, MenuTrigger, SplitButton, MenuPopover, MenuList, MenuItem, Toolbar as Toolbar$1, ToolbarRadioButton, MenuGroup, MenuGroupHeader, Switch as Switch$1, treeItemLevelToken, FlatTree, FlatTreeItem, TreeItemLayout, MenuDivider, MenuItemCheckbox, useMergedRefs, Input, Dropdown as Dropdown$1, Option, Popover as Popover$1, PopoverTrigger, PopoverSurface, ColorPicker, ColorArea, ColorSlider, AlphaSlider, ColorSwatch, PresenceBadge, Slider as Slider$1, MenuItemRadio, Dialog, DialogSurface, DialogBody, DialogTitle, DialogContent, DialogActions, List as List$1, ListItem, Badge, Label, MessageBarTitle, useComboboxFilter, Combobox, Subtitle2, Textarea as Textarea$1, ToolbarButton, ToolbarDivider, Field } from '@fluentui/react-components';
|
|
4
|
-
import { ErrorCircleRegular, EyeFilled, EyeOffRegular, CheckmarkFilled, EditRegular, FilterRegular, PinFilled, PinRegular, ArrowCircleUpRegular, ChevronCircleRight16Regular, ChevronCircleRight20Regular, ChevronCircleDown16Regular, ChevronCircleDown20Regular, Copy16Regular, CopyRegular, PanelLeftExpandRegular, PanelRightExpandRegular, PanelLeftContractRegular, PanelRightContractRegular, PictureInPictureEnterRegular, MoreHorizontalRegular, LayoutColumnTwoFocusLeftFilled, LayoutColumnTwoSplitLeftFocusTopLeftFilled, LayoutColumnTwoSplitLeftFocusBottomLeftFilled, LayoutColumnTwoFocusRightFilled, LayoutColumnTwoSplitRightFocusTopRightFilled, LayoutColumnTwoSplitRightFocusBottomRightFilled, SettingsRegular, DocumentTextRegular, createFluentIcon, TextSortAscendingRegular, GlobeRegular, WarningRegular, ArrowExpandAllRegular, ArrowCollapseAllRegular, CubeTreeRegular, BugRegular, ArrowUploadRegular, ArrowBidirectionalUpDownFilled, ArrowDownloadRegular, StopRegular, RecordRegular, DataBarHorizontalRegular, WrenchRegular, ArrowClockwiseRegular, WeatherSunnyRegular, WeatherMoonRegular, PlugConnectedRegular,
|
|
4
|
+
import { ErrorCircleRegular, EyeFilled, EyeOffRegular, CheckmarkFilled, EditRegular, FilterRegular, PinFilled, PinRegular, ArrowCircleUpRegular, ChevronCircleRight16Regular, ChevronCircleRight20Regular, ChevronCircleDown16Regular, ChevronCircleDown20Regular, Copy16Regular, CopyRegular, PanelLeftExpandRegular, PanelRightExpandRegular, PanelLeftContractRegular, PanelRightContractRegular, PictureInPictureEnterRegular, MoreHorizontalRegular, LayoutColumnTwoFocusLeftFilled, LayoutColumnTwoSplitLeftFocusTopLeftFilled, LayoutColumnTwoSplitLeftFocusBottomLeftFilled, LayoutColumnTwoFocusRightFilled, LayoutColumnTwoSplitRightFocusTopRightFilled, LayoutColumnTwoSplitRightFocusBottomRightFilled, SettingsRegular, DocumentTextRegular, createFluentIcon, TextSortAscendingRegular, GlobeRegular, WarningRegular, ArrowExpandAllRegular, ArrowCollapseAllRegular, CubeTreeRegular, BugRegular, ArrowUploadRegular, ArrowBidirectionalUpDownFilled, ArrowDownloadRegular, StopRegular, RecordRegular, DataBarHorizontalRegular, WrenchRegular, ArrowClockwiseRegular, WeatherSunnyRegular, WeatherMoonRegular, PlugDisconnectedRegular, PlugConnectedRegular, PlugConnectedCheckmarkRegular, ArrowRotateClockwiseRegular, ArrowExpandRegular, SelectObjectRegular, CubeRegular, CameraRegular, AddRegular, DeleteRegular, FullScreenMaximizeRegular, ChevronDownRegular, ChevronRightRegular, CircleSmallFilled, SaveRegular, PreviousRegular, ArrowPreviousRegular, TriangleLeftRegular, RecordStopRegular, PlayRegular, ArrowNextRegular, NextRegular, PauseRegular, LinkDismissRegular, LinkEditRegular, ArrowUndoRegular, BracesRegular, BracesDismiss16Regular, EyeRegular, CloudArrowUpRegular, CloudArrowDownRegular, EyeOffFilled, ArrowMoveFilled, StopFilled, PlayFilled, LockOpenRegular, LockClosedRegular, ResizeRegular, ChevronUpRegular, ArrowResetRegular, CircleHalfFillRegular, EyedropperRegular, PaintBucketRegular, InkStrokeRegular, StackRegular, FilmstripRegular, PauseFilled, WeatherSunnyLowFilled, LayerRegular, FrameRegular, AppGenericRegular, RectangleLandscapeRegular, BorderOutsideRegular, BorderNoneRegular, MyLocationRegular, BubbleMultipleRegular, LightbulbRegular, VideoFilled, VideoRegular, FlashlightRegular, FlashlightOffRegular, DropRegular, BlurRegular, PipelineRegular, PersonWalkingRegular, DataLineRegular, SoundWaveCircleRegular, PersonSquareRegular, LayerDiagonalPersonRegular, ImageEditRegular, ImageRegular, TargetRegular, PersonFeedbackRegular, BranchRegular, DeleteFilled } from '@fluentui/react-icons';
|
|
5
5
|
import { Color3, Color4 } from '@babylonjs/core/Maths/math.color.js';
|
|
6
6
|
import { Vector3, Quaternion, Matrix, Vector2, Vector4, TmpVectors } from '@babylonjs/core/Maths/math.vector.js';
|
|
7
7
|
import { Observable } from '@babylonjs/core/Misc/observable.js';
|
|
@@ -281,7 +281,7 @@ const Button = forwardRef((props, ref) => {
|
|
|
281
281
|
});
|
|
282
282
|
Button.displayName = "Button";
|
|
283
283
|
|
|
284
|
-
const useStyles$
|
|
284
|
+
const useStyles$_ = makeStyles({
|
|
285
285
|
root: {
|
|
286
286
|
display: "flex",
|
|
287
287
|
flexDirection: "column",
|
|
@@ -362,7 +362,7 @@ class ErrorBoundary extends Component {
|
|
|
362
362
|
}
|
|
363
363
|
}
|
|
364
364
|
function ErrorFallback({ error, onRetry }) {
|
|
365
|
-
const styles = useStyles$
|
|
365
|
+
const styles = useStyles$_();
|
|
366
366
|
return (jsxs("div", { className: styles.root, children: [jsx(ErrorCircleRegular, { className: styles.icon }), jsx("div", { className: styles.title, children: "Something went wrong" }), jsx("div", { className: styles.message, children: "An error occurred in this component. You can try again or continue using other parts of the tool." }), jsx(Button, { label: "Try Again", appearance: "primary", onClick: onRetry }), error && jsx("div", { className: styles.details, children: error.message })] }));
|
|
367
367
|
}
|
|
368
368
|
|
|
@@ -1277,12 +1277,12 @@ function useAccordionSectionItemState(props) {
|
|
|
1277
1277
|
// Debug: warn if itemId changes (should be stable)
|
|
1278
1278
|
const prevItemIdRef = useRef(itemId);
|
|
1279
1279
|
useEffect(() => {
|
|
1280
|
-
if (prevItemIdRef.current !== itemId) {
|
|
1280
|
+
if (accordionCtx && prevItemIdRef.current !== itemId) {
|
|
1281
1281
|
Logger.Warn(`Accordion: The uniqueId "${itemId}" in section "${sectionCtx?.sectionId}" has changed from "${prevItemIdRef.current}". ` +
|
|
1282
1282
|
`Each item must have a unique, stable ID for pin/hide persistence to work correctly.`);
|
|
1283
1283
|
}
|
|
1284
1284
|
prevItemIdRef.current = itemId;
|
|
1285
|
-
}, [itemId, sectionCtx?.sectionId]);
|
|
1285
|
+
}, [accordionCtx, itemId, sectionCtx?.sectionId]);
|
|
1286
1286
|
// Register item and detect duplicates (skip nested items, as children of other AccordionSectionItem should not participate in pin/hide/search).
|
|
1287
1287
|
useEffect(() => {
|
|
1288
1288
|
if (!accordionCtx || !itemUniqueId || isNested) {
|
|
@@ -1363,7 +1363,7 @@ function useIsSectionEmpty(sectionId) {
|
|
|
1363
1363
|
return hasItems;
|
|
1364
1364
|
}
|
|
1365
1365
|
|
|
1366
|
-
const useStyles$
|
|
1366
|
+
const useStyles$Z = makeStyles({
|
|
1367
1367
|
accordion: {
|
|
1368
1368
|
display: "flex",
|
|
1369
1369
|
flexDirection: "column",
|
|
@@ -1455,7 +1455,7 @@ const useStyles$Y = makeStyles({
|
|
|
1455
1455
|
*/
|
|
1456
1456
|
const AccordionMenuBar = () => {
|
|
1457
1457
|
AccordionMenuBar.displayName = "AccordionMenuBar";
|
|
1458
|
-
const classes = useStyles$
|
|
1458
|
+
const classes = useStyles$Z();
|
|
1459
1459
|
const accordionCtx = useContext(AccordionContext);
|
|
1460
1460
|
if (!accordionCtx) {
|
|
1461
1461
|
return null;
|
|
@@ -1479,7 +1479,7 @@ const AccordionMenuBar = () => {
|
|
|
1479
1479
|
const AccordionSectionBlock = (props) => {
|
|
1480
1480
|
AccordionSectionBlock.displayName = "AccordionSectionBlock";
|
|
1481
1481
|
const { children, sectionId } = props;
|
|
1482
|
-
const classes = useStyles$
|
|
1482
|
+
const classes = useStyles$Z();
|
|
1483
1483
|
const accordionCtx = useContext(AccordionContext);
|
|
1484
1484
|
const { context: sectionContext, isEmpty } = useAccordionSectionBlockContext(props);
|
|
1485
1485
|
if (accordionCtx) {
|
|
@@ -1499,7 +1499,7 @@ const AccordionSectionBlock = (props) => {
|
|
|
1499
1499
|
const AccordionSectionItem = (props) => {
|
|
1500
1500
|
AccordionSectionItem.displayName = "AccordionSectionItem";
|
|
1501
1501
|
const { children, staticItem } = props;
|
|
1502
|
-
const classes = useStyles$
|
|
1502
|
+
const classes = useStyles$Z();
|
|
1503
1503
|
const accordionCtx = useContext(AccordionContext);
|
|
1504
1504
|
const itemState = useAccordionSectionItemState(props);
|
|
1505
1505
|
const [ctrlMode, setCtrlMode] = useState(false);
|
|
@@ -1539,7 +1539,7 @@ const AccordionSectionItem = (props) => {
|
|
|
1539
1539
|
*/
|
|
1540
1540
|
const AccordionPinnedContainer = () => {
|
|
1541
1541
|
AccordionPinnedContainer.displayName = "AccordionPinnedContainer";
|
|
1542
|
-
const classes = useStyles$
|
|
1542
|
+
const classes = useStyles$Z();
|
|
1543
1543
|
const accordionCtx = useContext(AccordionContext);
|
|
1544
1544
|
return (jsx("div", { ref: accordionCtx?.pinnedContainerRef, className: classes.pinnedContainer, children: jsx(MessageBar$1, { className: classes.pinnedContainerEmpty, children: jsx(MessageBarBody, { children: "No pinned items" }) }) }));
|
|
1545
1545
|
};
|
|
@@ -1550,7 +1550,7 @@ const AccordionPinnedContainer = () => {
|
|
|
1550
1550
|
*/
|
|
1551
1551
|
const AccordionSearchBox = () => {
|
|
1552
1552
|
AccordionSearchBox.displayName = "AccordionSearchBox";
|
|
1553
|
-
const classes = useStyles$
|
|
1553
|
+
const classes = useStyles$Z();
|
|
1554
1554
|
const accordionCtx = useContext(AccordionContext);
|
|
1555
1555
|
if (!accordionCtx?.features.search) {
|
|
1556
1556
|
return null;
|
|
@@ -1566,7 +1566,7 @@ const AccordionSearchBox = () => {
|
|
|
1566
1566
|
*/
|
|
1567
1567
|
const AccordionSection = (props) => {
|
|
1568
1568
|
AccordionSection.displayName = "AccordionSection";
|
|
1569
|
-
const classes = useStyles$
|
|
1569
|
+
const classes = useStyles$Z();
|
|
1570
1570
|
return jsx("div", { className: classes.panelDiv, children: props.children });
|
|
1571
1571
|
};
|
|
1572
1572
|
const StringAccordion = Accordion$1;
|
|
@@ -1574,7 +1574,7 @@ const Accordion = forwardRef((props, ref) => {
|
|
|
1574
1574
|
Accordion.displayName = "Accordion";
|
|
1575
1575
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1576
1576
|
const { children, highlightSections, uniqueId, enablePinnedItems, enableHiddenItems, enableSearchItems, ...rest } = props;
|
|
1577
|
-
const classes = useStyles$
|
|
1577
|
+
const classes = useStyles$Z();
|
|
1578
1578
|
const { size } = useContext(ToolContext);
|
|
1579
1579
|
const accordionCtx = useAccordionContext(props);
|
|
1580
1580
|
const hasPinning = accordionCtx?.features.pinning ?? false;
|
|
@@ -1671,7 +1671,7 @@ const Collapse = (props) => {
|
|
|
1671
1671
|
return (jsx(Collapse$1, { visible: props.visible, orientation: props.orientation, unmountOnExit: true, children: jsx("div", { className: `${classes.collapseContent} ${props.orientation === "horizontal" ? classes.horizontal : classes.vertical}`, children: props.children }) }));
|
|
1672
1672
|
};
|
|
1673
1673
|
|
|
1674
|
-
const useStyles$
|
|
1674
|
+
const useStyles$Y = makeStyles({
|
|
1675
1675
|
button: {
|
|
1676
1676
|
display: "flex",
|
|
1677
1677
|
alignItems: "center",
|
|
@@ -1689,7 +1689,7 @@ const ToggleButton = (props) => {
|
|
|
1689
1689
|
ToggleButton.displayName = "ToggleButton";
|
|
1690
1690
|
const { value, onChange, title, appearance = "subtle" } = props;
|
|
1691
1691
|
const { size } = useContext(ToolContext);
|
|
1692
|
-
const classes = useStyles$
|
|
1692
|
+
const classes = useStyles$Y();
|
|
1693
1693
|
const [checked, setChecked] = useState(value);
|
|
1694
1694
|
const toggle = useCallback(() => {
|
|
1695
1695
|
setChecked((prevChecked) => {
|
|
@@ -1998,7 +1998,7 @@ const UXContextProvider = (props) => {
|
|
|
1998
1998
|
function AsReadonlyArray(array) {
|
|
1999
1999
|
return array;
|
|
2000
2000
|
}
|
|
2001
|
-
const useStyles$
|
|
2001
|
+
const useStyles$X = makeStyles({
|
|
2002
2002
|
rootDiv: {
|
|
2003
2003
|
flex: 1,
|
|
2004
2004
|
overflow: "hidden",
|
|
@@ -2013,7 +2013,7 @@ const useStyles$W = makeStyles({
|
|
|
2013
2013
|
* @returns The extensible accordion component.
|
|
2014
2014
|
*/
|
|
2015
2015
|
function ExtensibleAccordion(props) {
|
|
2016
|
-
const classes = useStyles$
|
|
2016
|
+
const classes = useStyles$X();
|
|
2017
2017
|
const { children, sections, sectionContent, context, sectionsRef, ...rest } = props;
|
|
2018
2018
|
const defaultSections = useMemo(() => {
|
|
2019
2019
|
const defaultSections = [];
|
|
@@ -2138,7 +2138,7 @@ function ExtensibleAccordion(props) {
|
|
|
2138
2138
|
})] }) })) }));
|
|
2139
2139
|
}
|
|
2140
2140
|
|
|
2141
|
-
const useStyles$
|
|
2141
|
+
const useStyles$W = makeStyles({
|
|
2142
2142
|
paneRootDiv: {
|
|
2143
2143
|
display: "flex",
|
|
2144
2144
|
flex: 1,
|
|
@@ -2151,7 +2151,7 @@ const useStyles$V = makeStyles({
|
|
|
2151
2151
|
*/
|
|
2152
2152
|
const SidePaneContainer = forwardRef((props, ref) => {
|
|
2153
2153
|
const { className, ...rest } = props;
|
|
2154
|
-
const classes = useStyles$
|
|
2154
|
+
const classes = useStyles$W();
|
|
2155
2155
|
return (jsx("div", { className: mergeClasses(classes.paneRootDiv, className), ref: ref, ...rest, children: props.children }));
|
|
2156
2156
|
});
|
|
2157
2157
|
|
|
@@ -2422,7 +2422,7 @@ function useTheme(invert = false) {
|
|
|
2422
2422
|
}
|
|
2423
2423
|
|
|
2424
2424
|
// Fluent doesn't apply styling to scrollbars by default, so provide our own reasonable default.
|
|
2425
|
-
const useStyles$
|
|
2425
|
+
const useStyles$V = makeStyles({
|
|
2426
2426
|
root: {
|
|
2427
2427
|
scrollbarColor: `${tokens.colorNeutralForeground3} ${tokens.colorTransparentBackground}`,
|
|
2428
2428
|
},
|
|
@@ -2438,11 +2438,11 @@ const Theme = (props) => {
|
|
|
2438
2438
|
// break any UI within the portal. Therefore, default to false.
|
|
2439
2439
|
const { invert = false, applyStylesToPortals = false, className, ...rest } = props;
|
|
2440
2440
|
const theme = useTheme(invert);
|
|
2441
|
-
const classes = useStyles$
|
|
2441
|
+
const classes = useStyles$V();
|
|
2442
2442
|
return (jsx(FluentProvider, { theme: theme, className: mergeClasses(classes.root, className), applyStylesToPortals: applyStylesToPortals, ...rest, children: props.children }));
|
|
2443
2443
|
};
|
|
2444
2444
|
|
|
2445
|
-
const useStyles$
|
|
2445
|
+
const useStyles$U = makeStyles({
|
|
2446
2446
|
extensionTeachingPopover: {
|
|
2447
2447
|
maxWidth: "320px",
|
|
2448
2448
|
},
|
|
@@ -2453,7 +2453,7 @@ const useStyles$T = makeStyles({
|
|
|
2453
2453
|
* @returns The teaching moment popover.
|
|
2454
2454
|
*/
|
|
2455
2455
|
const TeachingMoment = ({ shouldDisplay, positioningRef, onOpenChange, title, description }) => {
|
|
2456
|
-
const classes = useStyles$
|
|
2456
|
+
const classes = useStyles$U();
|
|
2457
2457
|
return (jsx(TeachingPopover, { appearance: "brand", open: shouldDisplay, positioning: { positioningRef }, onOpenChange: onOpenChange, children: jsxs(TeachingPopoverSurface, { className: classes.extensionTeachingPopover, children: [jsx(TeachingPopoverHeader, { children: title }), jsx(TeachingPopoverBody, { children: description })] }) }));
|
|
2458
2458
|
};
|
|
2459
2459
|
|
|
@@ -2945,7 +2945,7 @@ const RootComponentServiceIdentity = Symbol("RootComponent");
|
|
|
2945
2945
|
* The unique identity symbol for the shell service.
|
|
2946
2946
|
*/
|
|
2947
2947
|
const ShellServiceIdentity = Symbol("ShellService");
|
|
2948
|
-
const useStyles$
|
|
2948
|
+
const useStyles$T = makeStyles({
|
|
2949
2949
|
mainView: {
|
|
2950
2950
|
flex: 1,
|
|
2951
2951
|
display: "flex",
|
|
@@ -3158,14 +3158,14 @@ const DockMenu = (props) => {
|
|
|
3158
3158
|
};
|
|
3159
3159
|
const PaneHeader = (props) => {
|
|
3160
3160
|
const { id, title, dockOptions } = props;
|
|
3161
|
-
const classes = useStyles$
|
|
3161
|
+
const classes = useStyles$T();
|
|
3162
3162
|
return (jsxs("div", { className: classes.paneHeaderDiv, children: [props.icon && (jsx("div", { className: classes.paneHeaderIcon, children: jsx(props.icon, {}) })), jsx(Subtitle2Stronger, { className: mergeClasses(classes.paneHeaderText, !props.icon && classes.paneHeaderTextNoIcon), children: title }), jsx(DockMenu, { sidePaneId: id, dockOptions: dockOptions, children: jsx(Button$1, { className: classes.paneHeaderButton, appearance: "transparent", icon: jsx(MoreHorizontalRegular, {}) }) })] }));
|
|
3163
3163
|
};
|
|
3164
3164
|
// This is a wrapper for an item in a toolbar that simply adds a teaching moment, which is useful for dynamically added items, possibly from extensions.
|
|
3165
3165
|
const ToolbarItem = (props) => {
|
|
3166
3166
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
3167
3167
|
const { verticalLocation, horizontalLocation, id, component: Component, displayName } = props;
|
|
3168
|
-
const classes = useStyles$
|
|
3168
|
+
const classes = useStyles$T();
|
|
3169
3169
|
const useTeachingMoment = useMemo(() => MakePopoverTeachingMoment(`Bar/${verticalLocation}/${horizontalLocation}/${displayName ?? id}`), [displayName, id]);
|
|
3170
3170
|
const teachingMoment = useTeachingMoment(props.teachingMoment === false);
|
|
3171
3171
|
const title = typeof props.teachingMoment === "object" ? props.teachingMoment.title : (displayName ?? id);
|
|
@@ -3175,7 +3175,7 @@ const ToolbarItem = (props) => {
|
|
|
3175
3175
|
// TODO: Handle overflow, possibly via https://react.fluentui.dev/?path=/docs/components-overflow--docs with priority.
|
|
3176
3176
|
// This component just renders a toolbar with left aligned toolbar items on the left and right aligned toolbar items on the right.
|
|
3177
3177
|
const Toolbar = ({ location, components }) => {
|
|
3178
|
-
const classes = useStyles$
|
|
3178
|
+
const classes = useStyles$T();
|
|
3179
3179
|
const leftComponents = useMemo(() => components.filter((entry) => entry.horizontalLocation === "left"), [components]);
|
|
3180
3180
|
const rightComponents = useMemo(() => components.filter((entry) => entry.horizontalLocation === "right"), [components]);
|
|
3181
3181
|
return (jsx(Fragment, { children: components.length > 0 && (jsxs("div", { className: `${classes.bar} ${location === "top" ? classes.barTop : classes.barBottom}`, children: [jsx("div", { className: classes.barLeft, children: leftComponents.map((entry) => (jsx(ToolbarItem, { verticalLocation: location, horizontalLocation: entry.horizontalLocation, id: entry.key, component: entry.component, displayName: entry.displayName, teachingMoment: entry.teachingMoment }, entry.key))) }), jsx("div", { className: classes.barRight, children: rightComponents.map((entry) => (jsx(ToolbarItem, { verticalLocation: location, horizontalLocation: entry.horizontalLocation, id: entry.key, component: entry.component, displayName: entry.displayName, teachingMoment: entry.teachingMoment }, entry.key))) })] })) }));
|
|
@@ -3185,7 +3185,7 @@ const SidePaneTab = (props) => {
|
|
|
3185
3185
|
const { location, id, isSelected, isFirst, isLast, dockOptions,
|
|
3186
3186
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
3187
3187
|
icon: Icon, title, } = props;
|
|
3188
|
-
const classes = useStyles$
|
|
3188
|
+
const classes = useStyles$T();
|
|
3189
3189
|
const useTeachingMoment = useMemo(() => MakePopoverTeachingMoment(`Pane/${location}/${title ?? id}`), [title, id]);
|
|
3190
3190
|
const teachingMoment = useTeachingMoment(props.teachingMoment === false);
|
|
3191
3191
|
const tabClass = mergeClasses(classes.tab, isSelected ? classes.selectedTab : classes.unselectedTab, isFirst ? classes.firstTab : undefined, isLast ? classes.lastTab : undefined);
|
|
@@ -3197,7 +3197,7 @@ const SidePaneTab = (props) => {
|
|
|
3197
3197
|
// In "compact" mode, the tab list is integrated into the pane itself.
|
|
3198
3198
|
// In "full" mode, the returned tab list is later injected into the toolbar.
|
|
3199
3199
|
function usePane(location, defaultWidth, minWidth, sidePanes, onSelectSidePane, dockOperations, toolbarMode, topBarItems, bottomBarItems, initialCollapsed) {
|
|
3200
|
-
const classes = useStyles$
|
|
3200
|
+
const classes = useStyles$T();
|
|
3201
3201
|
const [topSelectedTab, setTopSelectedTab] = useState();
|
|
3202
3202
|
const [bottomSelectedTab, setBottomSelectedTab] = useState();
|
|
3203
3203
|
const [collapsed, setCollapsed] = useState(initialCollapsed);
|
|
@@ -3394,7 +3394,7 @@ function MakeShellServiceDefinition({ leftPaneDefaultWidth = 350, leftPaneMinWid
|
|
|
3394
3394
|
expand: () => onCollapseChanged.notifyObservers({ location: "right", collapsed: false }),
|
|
3395
3395
|
};
|
|
3396
3396
|
const rootComponent = () => {
|
|
3397
|
-
const classes = useStyles$
|
|
3397
|
+
const classes = useStyles$T();
|
|
3398
3398
|
const [sidePaneDockOverrides, setSidePaneDockOverrides] = useSetting(SidePaneDockOverridesSettingDescriptor);
|
|
3399
3399
|
// This function returns a promise that resolves after the dock change takes effect so that
|
|
3400
3400
|
// we can then select the re-docked pane.
|
|
@@ -3781,13 +3781,13 @@ function useImpulse() {
|
|
|
3781
3781
|
return [value, pulse];
|
|
3782
3782
|
}
|
|
3783
3783
|
|
|
3784
|
-
const useStyles$
|
|
3784
|
+
const useStyles$S = makeStyles({
|
|
3785
3785
|
placeholderDiv: {
|
|
3786
3786
|
padding: `${tokens.spacingVerticalM} ${tokens.spacingHorizontalM}`,
|
|
3787
3787
|
},
|
|
3788
3788
|
});
|
|
3789
3789
|
const PropertiesPane = (props) => {
|
|
3790
|
-
const classes = useStyles$
|
|
3790
|
+
const classes = useStyles$S();
|
|
3791
3791
|
const entity = props.context;
|
|
3792
3792
|
return entity != null ? (jsx(ExtensibleAccordion, { ...props })) : (jsx("div", { className: classes.placeholderDiv, children: jsx(Body1Strong, { italic: true, children: "No entity selected." }) }));
|
|
3793
3793
|
};
|
|
@@ -4227,7 +4227,7 @@ function CoerceEntityArray(entities, sort) {
|
|
|
4227
4227
|
}
|
|
4228
4228
|
return entities;
|
|
4229
4229
|
}
|
|
4230
|
-
const useStyles$
|
|
4230
|
+
const useStyles$R = makeStyles({
|
|
4231
4231
|
rootDiv: {
|
|
4232
4232
|
flex: 1,
|
|
4233
4233
|
overflow: "hidden",
|
|
@@ -4336,14 +4336,14 @@ function MakeInlineCommandElement(command, isPlaceholder) {
|
|
|
4336
4336
|
}
|
|
4337
4337
|
const SceneTreeItem = (props) => {
|
|
4338
4338
|
const { isSelected, select } = props;
|
|
4339
|
-
const classes = useStyles$
|
|
4339
|
+
const classes = useStyles$R();
|
|
4340
4340
|
const [compactMode] = useSetting(CompactModeSettingDescriptor);
|
|
4341
4341
|
const treeItemLayoutClass = mergeClasses(classes.sceneTreeItemLayout, compactMode ? classes.treeItemLayoutCompact : undefined);
|
|
4342
4342
|
return (jsx(FlatTreeItem, { className: classes.treeItem, value: "scene", itemType: "leaf", parentValue: undefined, "aria-level": 1, "aria-setsize": 1, "aria-posinset": 1, onClick: select, children: jsx(TreeItemLayout, { iconBefore: jsx(GlobeRegular, {}), className: treeItemLayoutClass, style: isSelected ? { backgroundColor: tokens.colorNeutralBackground1Selected } : undefined, children: jsx(Body1Strong, { wrap: false, truncate: true, children: "Scene" }) }) }, "scene"));
|
|
4343
4343
|
};
|
|
4344
4344
|
const SectionTreeItem = (props) => {
|
|
4345
4345
|
const { section, isFiltering, commandProviders, expandAll, collapseAll, isDropTarget, ...dropProps } = props;
|
|
4346
|
-
const classes = useStyles$
|
|
4346
|
+
const classes = useStyles$R();
|
|
4347
4347
|
const [compactMode] = useSetting(CompactModeSettingDescriptor);
|
|
4348
4348
|
// Get the commands that apply to this section.
|
|
4349
4349
|
const commands = useResource(useCallback(() => {
|
|
@@ -4360,7 +4360,7 @@ const SectionTreeItem = (props) => {
|
|
|
4360
4360
|
};
|
|
4361
4361
|
const EntityTreeItem = (props) => {
|
|
4362
4362
|
const { entityItem, isSelected, select, isFiltering, commandProviders, expandAll, collapseAll, isDragging, isDropTarget, ...dragProps } = props;
|
|
4363
|
-
const classes = useStyles$
|
|
4363
|
+
const classes = useStyles$R();
|
|
4364
4364
|
const [compactMode] = useSetting(CompactModeSettingDescriptor);
|
|
4365
4365
|
const hasChildren = !!entityItem.children?.length;
|
|
4366
4366
|
const displayInfo = useResource(useCallback(() => {
|
|
@@ -4476,7 +4476,7 @@ const EntityTreeItem = (props) => {
|
|
|
4476
4476
|
}, children: jsx(Tooltip$1, { content: name, relationship: "description", children: jsx(Body1, { wrap: false, truncate: true, children: name }) }) }) }, GetEntityId$1(entityItem.entity)) }), jsx(MenuPopover, { hidden: !hasChildren && contextMenuCommands.length === 0, children: jsxs(MenuList, { children: [hasChildren && (jsxs(Fragment, { children: [jsx(MenuItem, { icon: jsx(ArrowExpandAllRegular, {}), onClick: expandAll, children: jsx(Body1, { children: "Expand All" }) }), jsx(MenuItem, { icon: jsx(ArrowCollapseAllRegular, {}), onClick: collapseAll, children: jsx(Body1, { children: "Collapse All" }) })] })), hasChildren && contextMenuCommands.length > 0 && jsx(MenuDivider, {}), contextMenuItems] }) })] }));
|
|
4477
4477
|
};
|
|
4478
4478
|
const SceneExplorer = (props) => {
|
|
4479
|
-
const classes = useStyles$
|
|
4479
|
+
const classes = useStyles$R();
|
|
4480
4480
|
const { sections, entityCommandProviders, sectionCommandProviders, scene, selectedEntity = null } = props;
|
|
4481
4481
|
const [openItems, setOpenItems] = useState(new Set());
|
|
4482
4482
|
const [sceneVersion, setSceneVersion] = useState(0);
|
|
@@ -6102,7 +6102,7 @@ class CanvasGraphService {
|
|
|
6102
6102
|
}
|
|
6103
6103
|
}
|
|
6104
6104
|
|
|
6105
|
-
const useStyles$
|
|
6105
|
+
const useStyles$Q = makeStyles({
|
|
6106
6106
|
canvas: {
|
|
6107
6107
|
flexGrow: 1,
|
|
6108
6108
|
width: "100%",
|
|
@@ -6111,7 +6111,7 @@ const useStyles$P = makeStyles({
|
|
|
6111
6111
|
});
|
|
6112
6112
|
const CanvasGraph = (props) => {
|
|
6113
6113
|
const { collector, scene, layoutObservable, returnToPlayheadObservable, onVisibleRangeChangedObservable, initialGraphSize } = props;
|
|
6114
|
-
const classes = useStyles$
|
|
6114
|
+
const classes = useStyles$Q();
|
|
6115
6115
|
const canvasRef = useRef(null);
|
|
6116
6116
|
useEffect(() => {
|
|
6117
6117
|
if (!canvasRef.current) {
|
|
@@ -6188,7 +6188,7 @@ function EvaluateExpression(rawValue) {
|
|
|
6188
6188
|
return NaN;
|
|
6189
6189
|
}
|
|
6190
6190
|
}
|
|
6191
|
-
const useStyles$
|
|
6191
|
+
const useStyles$P = makeStyles({
|
|
6192
6192
|
icon: {
|
|
6193
6193
|
"&:hover": {
|
|
6194
6194
|
color: tokens.colorBrandForeground1,
|
|
@@ -6202,7 +6202,7 @@ const useStyles$O = makeStyles({
|
|
|
6202
6202
|
const SpinButton = forwardRef((props, ref) => {
|
|
6203
6203
|
SpinButton.displayName = "SpinButton2";
|
|
6204
6204
|
const inputClasses = useInputStyles$1();
|
|
6205
|
-
const classes = useStyles$
|
|
6205
|
+
const classes = useStyles$P();
|
|
6206
6206
|
const { size } = useContext(ToolContext);
|
|
6207
6207
|
const { min, max } = props;
|
|
6208
6208
|
const baseStep = props.step ?? 1;
|
|
@@ -6469,7 +6469,7 @@ const Dropdown = (props) => {
|
|
|
6469
6469
|
const NumberDropdown = Dropdown;
|
|
6470
6470
|
const StringDropdown = Dropdown;
|
|
6471
6471
|
|
|
6472
|
-
const useStyles$
|
|
6472
|
+
const useStyles$O = makeStyles({
|
|
6473
6473
|
surface: {
|
|
6474
6474
|
maxWidth: "400px",
|
|
6475
6475
|
},
|
|
@@ -6484,7 +6484,7 @@ const useStyles$N = makeStyles({
|
|
|
6484
6484
|
const Popover = forwardRef((props, ref) => {
|
|
6485
6485
|
const { children, open: controlledOpen, onOpenChange, positioning, surfaceClassName } = props;
|
|
6486
6486
|
const [internalOpen, setInternalOpen] = useState(false);
|
|
6487
|
-
const classes = useStyles$
|
|
6487
|
+
const classes = useStyles$O();
|
|
6488
6488
|
const isControlled = controlledOpen !== undefined;
|
|
6489
6489
|
const popoverOpen = isControlled ? controlledOpen : internalOpen;
|
|
6490
6490
|
const handleOpenChange = (_, data) => {
|
|
@@ -6728,7 +6728,7 @@ const InputAlphaField = (props) => {
|
|
|
6728
6728
|
} }));
|
|
6729
6729
|
};
|
|
6730
6730
|
|
|
6731
|
-
const useStyles$
|
|
6731
|
+
const useStyles$N = makeStyles({
|
|
6732
6732
|
sidebar: {
|
|
6733
6733
|
display: "flex",
|
|
6734
6734
|
flexDirection: "column",
|
|
@@ -6792,7 +6792,7 @@ const useStyles$M = makeStyles({
|
|
|
6792
6792
|
});
|
|
6793
6793
|
const PerformanceSidebar = (props) => {
|
|
6794
6794
|
const { collector, onVisibleRangeChangedObservable } = props;
|
|
6795
|
-
const classes = useStyles$
|
|
6795
|
+
const classes = useStyles$N();
|
|
6796
6796
|
// Map from id to IPerfMetadata information
|
|
6797
6797
|
const [metadataMap, setMetadataMap] = useState();
|
|
6798
6798
|
// Map from category to all the ids belonging to that category
|
|
@@ -6865,7 +6865,7 @@ const PerformanceSidebar = (props) => {
|
|
|
6865
6865
|
})] }, `category-${category || "version"}`))) }));
|
|
6866
6866
|
};
|
|
6867
6867
|
|
|
6868
|
-
const useStyles$
|
|
6868
|
+
const useStyles$M = makeStyles({
|
|
6869
6869
|
container: {
|
|
6870
6870
|
display: "flex",
|
|
6871
6871
|
flexDirection: "row",
|
|
@@ -6894,7 +6894,7 @@ const useStyles$L = makeStyles({
|
|
|
6894
6894
|
});
|
|
6895
6895
|
const PerformanceViewer = (props) => {
|
|
6896
6896
|
const { scene, layoutObservable, returnToLiveObservable, performanceCollector, initialGraphSize } = props;
|
|
6897
|
-
const classes = useStyles$
|
|
6897
|
+
const classes = useStyles$M();
|
|
6898
6898
|
const [onVisibleRangeChangedObservable] = useState(() => new Observable());
|
|
6899
6899
|
const onReturnToPlayheadClick = () => {
|
|
6900
6900
|
returnToLiveObservable.notifyObservers();
|
|
@@ -7061,14 +7061,14 @@ const TextPropertyLine = (props) => {
|
|
|
7061
7061
|
return (jsx(PropertyLine, { ...props, children: jsx(Body1, { title: title, children: value ?? "" }) }));
|
|
7062
7062
|
};
|
|
7063
7063
|
|
|
7064
|
-
const useStyles$
|
|
7064
|
+
const useStyles$L = makeStyles({
|
|
7065
7065
|
pinnedStatsPane: {
|
|
7066
7066
|
flex: "0 1 auto",
|
|
7067
7067
|
paddingBottom: tokens.spacingHorizontalM,
|
|
7068
7068
|
},
|
|
7069
7069
|
});
|
|
7070
7070
|
const StatsPane = (props) => {
|
|
7071
|
-
const classes = useStyles$
|
|
7071
|
+
const classes = useStyles$L();
|
|
7072
7072
|
const scene = props.context;
|
|
7073
7073
|
const engine = scene.getEngine();
|
|
7074
7074
|
const pollingObservable = usePollingObservable(250);
|
|
@@ -7231,7 +7231,7 @@ const ToolsServiceDefinition = {
|
|
|
7231
7231
|
*/
|
|
7232
7232
|
const ReactContextServiceIdentity = Symbol("ReactContextService");
|
|
7233
7233
|
|
|
7234
|
-
const useStyles$
|
|
7234
|
+
const useStyles$K = makeStyles({
|
|
7235
7235
|
dropdown: {
|
|
7236
7236
|
...UniformWidthStyling,
|
|
7237
7237
|
},
|
|
@@ -7243,7 +7243,7 @@ const useStyles$J = makeStyles({
|
|
|
7243
7243
|
*/
|
|
7244
7244
|
const DropdownPropertyLine = forwardRef((props, ref) => {
|
|
7245
7245
|
DropdownPropertyLine.displayName = "DropdownPropertyLine";
|
|
7246
|
-
const classes = useStyles$
|
|
7246
|
+
const classes = useStyles$K();
|
|
7247
7247
|
return (jsx(PropertyLine, { ...props, ref: ref, children: jsx(Dropdown, { ...props, className: classes.dropdown }) }));
|
|
7248
7248
|
});
|
|
7249
7249
|
/**
|
|
@@ -7401,7 +7401,7 @@ const SyncedSliderInput = (props) => {
|
|
|
7401
7401
|
return (jsxs("div", { className: mergeClasses(classes.container, props.className), children: [infoLabel && jsx(InfoLabel, { ...infoLabel, htmlFor: "syncedSlider" }), jsxs("div", { id: "syncedSlider", className: classes.syncedSlider, children: [hasSlider && (jsx(Slider, { className: getSliderClassName(), value: value, onChange: handleSliderChange, min: props.min, max: props.max, step: props.step, disabled: props.disabled, onPointerDown: handleSliderPointerDown, onPointerUp: handleSliderPointerUp })), jsx(SpinButton, { ...passthroughProps, className: useCompactSizing ? classes.compactSpinButton : classes.spinButton, inputClassName: useCompactSizing ? classes.compactSpinButtonInput : classes.spinButtonInput, value: value, onChange: handleInputChange, step: props.step, disabled: props.disabled, disableDragButton: true })] })] }));
|
|
7402
7402
|
};
|
|
7403
7403
|
|
|
7404
|
-
const useStyles$
|
|
7404
|
+
const useStyles$J = makeStyles({
|
|
7405
7405
|
uniformWidth: {
|
|
7406
7406
|
...UniformWidthStyling,
|
|
7407
7407
|
},
|
|
@@ -7413,7 +7413,7 @@ const useStyles$I = makeStyles({
|
|
|
7413
7413
|
*/
|
|
7414
7414
|
const SyncedSliderPropertyLine = forwardRef((props, ref) => {
|
|
7415
7415
|
SyncedSliderPropertyLine.displayName = "SyncedSliderPropertyLine";
|
|
7416
|
-
const classes = useStyles$
|
|
7416
|
+
const classes = useStyles$J();
|
|
7417
7417
|
const { label, description, ...sliderProps } = props;
|
|
7418
7418
|
return (jsx(PropertyLine, { ref: ref, ...props, children: jsx(SyncedSliderInput, { ...sliderProps, className: mergeClasses(classes.uniformWidth, props.className) }) }));
|
|
7419
7419
|
});
|
|
@@ -8301,12 +8301,17 @@ class ServiceContainer {
|
|
|
8301
8301
|
}
|
|
8302
8302
|
}
|
|
8303
8303
|
|
|
8304
|
+
/**
|
|
8305
|
+
* The unique identity symbol for the toast service.
|
|
8306
|
+
*/
|
|
8307
|
+
const ToastServiceIdentity = Symbol("ToastService");
|
|
8308
|
+
|
|
8304
8309
|
const ExtensionManagerContext = createContext(undefined);
|
|
8305
8310
|
function useExtensionManager() {
|
|
8306
8311
|
return useContext(ExtensionManagerContext)?.extensionManager;
|
|
8307
8312
|
}
|
|
8308
8313
|
|
|
8309
|
-
const useStyles$
|
|
8314
|
+
const useStyles$I = makeStyles({
|
|
8310
8315
|
themeButton: {
|
|
8311
8316
|
margin: 0,
|
|
8312
8317
|
},
|
|
@@ -8325,7 +8330,7 @@ const ThemeSelectorServiceDefinition = {
|
|
|
8325
8330
|
teachingMoment: false,
|
|
8326
8331
|
order: -300,
|
|
8327
8332
|
component: () => {
|
|
8328
|
-
const classes = useStyles$
|
|
8333
|
+
const classes = useStyles$I();
|
|
8329
8334
|
const { isDarkMode, themeMode, setThemeMode } = useThemeMode();
|
|
8330
8335
|
const onSelectedThemeChange = useCallback((e, data) => {
|
|
8331
8336
|
setThemeMode(data.checkedItems.includes("System") ? "system" : data.checkedItems[0].toLocaleLowerCase());
|
|
@@ -8342,7 +8347,7 @@ const ThemeSelectorServiceDefinition = {
|
|
|
8342
8347
|
},
|
|
8343
8348
|
};
|
|
8344
8349
|
|
|
8345
|
-
const useStyles$
|
|
8350
|
+
const useStyles$H = makeStyles({
|
|
8346
8351
|
app: {
|
|
8347
8352
|
colorScheme: "light dark",
|
|
8348
8353
|
flexGrow: 1,
|
|
@@ -8385,11 +8390,21 @@ function MakeModularTool(options) {
|
|
|
8385
8390
|
settingsStore.writeSetting(ThemeModeSettingDescriptor, themeMode);
|
|
8386
8391
|
}
|
|
8387
8392
|
const modularToolRootComponent = () => {
|
|
8388
|
-
const classes = useStyles$
|
|
8393
|
+
const classes = useStyles$H();
|
|
8389
8394
|
const [extensionManagerContext, setExtensionManagerContext] = useState();
|
|
8390
8395
|
const [requiredExtensions, setRequiredExtensions] = useState();
|
|
8391
8396
|
const [requiredExtensionsDeferred, setRequiredExtensionsDeferred] = useState();
|
|
8392
8397
|
const [extensionInstallError, setExtensionInstallError] = useState();
|
|
8398
|
+
const [toastHandle, setToastHandle] = useState(null);
|
|
8399
|
+
const [toastQueue, setToastQueue] = useState([]);
|
|
8400
|
+
useEffect(() => {
|
|
8401
|
+
if (toastHandle && toastQueue.length > 0) {
|
|
8402
|
+
for (const { message, options } of toastQueue) {
|
|
8403
|
+
toastHandle.showToast(message, options);
|
|
8404
|
+
}
|
|
8405
|
+
setToastQueue([]);
|
|
8406
|
+
}
|
|
8407
|
+
}, [toastHandle, toastQueue]);
|
|
8393
8408
|
const [rootComponentService, setRootComponentService] = useState();
|
|
8394
8409
|
const [contexts, updateContexts] = useReducer((state, action) => {
|
|
8395
8410
|
switch (action.type) {
|
|
@@ -8430,6 +8445,16 @@ function MakeModularTool(options) {
|
|
|
8430
8445
|
},
|
|
8431
8446
|
}),
|
|
8432
8447
|
});
|
|
8448
|
+
// Expose the toast service so non-React code (e.g. Observable callbacks) can show toasts.
|
|
8449
|
+
await serviceContainer.addServiceAsync({
|
|
8450
|
+
friendlyName: "Toast Service",
|
|
8451
|
+
produces: [ToastServiceIdentity],
|
|
8452
|
+
factory: () => ({
|
|
8453
|
+
showToast: (message, options) => {
|
|
8454
|
+
setToastQueue((prev) => [...prev, { message, options }]);
|
|
8455
|
+
},
|
|
8456
|
+
}),
|
|
8457
|
+
});
|
|
8433
8458
|
// Register the shell service (top level toolbar/side pane UI layout).
|
|
8434
8459
|
await serviceContainer.addServiceAsync(MakeShellServiceDefinition(options));
|
|
8435
8460
|
// Register a service that simply consumes the services we need before first render.
|
|
@@ -8452,7 +8477,7 @@ function MakeModularTool(options) {
|
|
|
8452
8477
|
}
|
|
8453
8478
|
// Register the extension list service (for browsing/installing extensions) if extension feeds are provided.
|
|
8454
8479
|
if (extensionFeeds.length > 0) {
|
|
8455
|
-
const { ExtensionListServiceDefinition } = await import('./extensionsListService-
|
|
8480
|
+
const { ExtensionListServiceDefinition } = await import('./extensionsListService-DPHWDyzb.js');
|
|
8456
8481
|
await serviceContainer.addServiceAsync(ExtensionListServiceDefinition);
|
|
8457
8482
|
}
|
|
8458
8483
|
// Register all external services (that make up a unique tool).
|
|
@@ -8525,7 +8550,7 @@ function MakeModularTool(options) {
|
|
|
8525
8550
|
else {
|
|
8526
8551
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
8527
8552
|
const Content = rootComponentService.rootComponent;
|
|
8528
|
-
return (jsx(ReactContextsWrapper, { contexts: contexts, children: jsx(SettingsStoreContext.Provider, { value: settingsStore, children: jsx(ExtensionManagerContext.Provider, { value: extensionManagerContext, children: jsx(Theme, { className: classes.app, children: jsxs(ToastProvider, { children: [jsx(Dialog, { open: !!requiredExtensions, modalType: "alert", children: jsx(DialogSurface, { children: jsxs(DialogBody, { children: [jsx(DialogTitle, { children: "Required Extensions" }), jsxs(DialogContent, { children: ["Opening this URL requires the following extensions to be installed and enabled:", jsx("ul", { children: requiredExtensions?.map((name) => (jsx("li", { children: name }, name))) })] }), jsxs(DialogActions, { children: [jsx(Button$1, { appearance: "primary", onClick: onAcceptRequiredExtensions, children: "Install & Enable" }), jsx(Button$1, { appearance: "secondary", onClick: onRejectRequiredExtensions, children: "No Thanks" })] })] }) }) }), jsx(Dialog, { open: !!extensionInstallError, modalType: "alert", children: jsx(DialogSurface, { children: jsxs(DialogBody, { children: [jsx(DialogTitle, { children: jsxs("div", { className: classes.extensionErrorTitleDiv, children: ["Extension Install Error", jsx(ErrorCircleRegular, { className: classes.extensionErrorIcon })] }) }), jsx(DialogContent, { children: jsxs(List$1, { children: [jsx(ListItem, { children: jsx(Body1, { children: `Extension "${extensionInstallError?.extension.name}" failed to install and was removed.` }) }), jsx(ListItem, { children: jsx(Body1, { children: `${extensionInstallError?.error}` }) })] }) }), jsx(DialogActions, { children: jsx(Button$1, { appearance: "primary", onClick: onAcknowledgedExtensionInstallError, children: "Close" }) })] }) }) }), jsx(Suspense, { fallback: jsx(Spinner, { className: classes.spinner }), children: jsx(Content, {}) })] }) }) }) }) }));
|
|
8553
|
+
return (jsx(ReactContextsWrapper, { contexts: contexts, children: jsx(SettingsStoreContext.Provider, { value: settingsStore, children: jsx(ExtensionManagerContext.Provider, { value: extensionManagerContext, children: jsx(Theme, { className: classes.app, children: jsxs(ToastProvider, { imperativeRef: setToastHandle, children: [jsx(Dialog, { open: !!requiredExtensions, modalType: "alert", children: jsx(DialogSurface, { children: jsxs(DialogBody, { children: [jsx(DialogTitle, { children: "Required Extensions" }), jsxs(DialogContent, { children: ["Opening this URL requires the following extensions to be installed and enabled:", jsx("ul", { children: requiredExtensions?.map((name) => (jsx("li", { children: name }, name))) })] }), jsxs(DialogActions, { children: [jsx(Button$1, { appearance: "primary", onClick: onAcceptRequiredExtensions, children: "Install & Enable" }), jsx(Button$1, { appearance: "secondary", onClick: onRejectRequiredExtensions, children: "No Thanks" })] })] }) }) }), jsx(Dialog, { open: !!extensionInstallError, modalType: "alert", children: jsx(DialogSurface, { children: jsxs(DialogBody, { children: [jsx(DialogTitle, { children: jsxs("div", { className: classes.extensionErrorTitleDiv, children: ["Extension Install Error", jsx(ErrorCircleRegular, { className: classes.extensionErrorIcon })] }) }), jsx(DialogContent, { children: jsxs(List$1, { children: [jsx(ListItem, { children: jsx(Body1, { children: `Extension "${extensionInstallError?.extension.name}" failed to install and was removed.` }) }), jsx(ListItem, { children: jsx(Body1, { children: `${extensionInstallError?.error}` }) })] }) }), jsx(DialogActions, { children: jsx(Button$1, { appearance: "primary", onClick: onAcknowledgedExtensionInstallError, children: "Close" }) })] }) }) }), jsx(Suspense, { fallback: jsx(Spinner, { className: classes.spinner }), children: jsx(Content, {}) })] }) }) }) }) }));
|
|
8529
8554
|
}
|
|
8530
8555
|
};
|
|
8531
8556
|
// Set the container element to be a flex container so that the tool can be displayed properly.
|
|
@@ -8568,14 +8593,14 @@ const DefaultInspectorExtensionFeed = new BuiltInsExtensionFeed("Inspector", [
|
|
|
8568
8593
|
description: "Adds a new panel for easy creation of various Babylon assets. This is a WIP extension...expect changes!",
|
|
8569
8594
|
keywords: ["creation", "tools"],
|
|
8570
8595
|
...BabylonWebResources,
|
|
8571
|
-
getExtensionModuleAsync: async () => await import('./quickCreateToolsService-
|
|
8596
|
+
getExtensionModuleAsync: async () => await import('./quickCreateToolsService-DJ1GVvH-.js'),
|
|
8572
8597
|
},
|
|
8573
8598
|
{
|
|
8574
8599
|
name: "Reflector",
|
|
8575
8600
|
description: "Connects to the Reflector Bridge for real-time scene synchronization with the Babylon.js Sandbox.",
|
|
8576
8601
|
keywords: ["reflector", "bridge", "sync", "sandbox", "tools"],
|
|
8577
8602
|
...BabylonWebResources,
|
|
8578
|
-
getExtensionModuleAsync: async () => await import('./reflectorService-
|
|
8603
|
+
getExtensionModuleAsync: async () => await import('./reflectorService-Cd41l6Tr.js'),
|
|
8579
8604
|
},
|
|
8580
8605
|
]);
|
|
8581
8606
|
|
|
@@ -8840,25 +8865,34 @@ function MakeInspectableBridgeServiceDefinition(options) {
|
|
|
8840
8865
|
let ws = null;
|
|
8841
8866
|
let reconnectTimer = null;
|
|
8842
8867
|
let disposed = false;
|
|
8868
|
+
let enabled = options.autoStart;
|
|
8843
8869
|
let connected = false;
|
|
8844
8870
|
const onConnectionStatusChanged = new Observable();
|
|
8871
|
+
function notifyStatusChanged() {
|
|
8872
|
+
onConnectionStatusChanged.notifyObservers();
|
|
8873
|
+
}
|
|
8845
8874
|
function setConnected(value) {
|
|
8846
8875
|
if (connected !== value) {
|
|
8847
8876
|
connected = value;
|
|
8848
|
-
|
|
8877
|
+
notifyStatusChanged();
|
|
8849
8878
|
}
|
|
8850
8879
|
}
|
|
8851
8880
|
function sendToBridge(message) {
|
|
8852
8881
|
ws?.send(JSON.stringify(message));
|
|
8853
8882
|
}
|
|
8854
8883
|
function connect() {
|
|
8855
|
-
if (disposed) {
|
|
8884
|
+
if (disposed || !enabled) {
|
|
8856
8885
|
return;
|
|
8857
8886
|
}
|
|
8858
8887
|
try {
|
|
8888
|
+
// NOTE: The browser unconditionally logs a console error for failed WebSocket
|
|
8889
|
+
// connections at the network level. This cannot be suppressed from JavaScript.
|
|
8859
8890
|
ws = new WebSocket(`ws://127.0.0.1:${options.port}`);
|
|
8860
8891
|
}
|
|
8861
8892
|
catch {
|
|
8893
|
+
ws = null;
|
|
8894
|
+
setConnected(false);
|
|
8895
|
+
Logger.Warn(`InspectableBridgeService: Failed to create WebSocket connection on port ${options.port}.`);
|
|
8862
8896
|
scheduleReconnect();
|
|
8863
8897
|
return;
|
|
8864
8898
|
}
|
|
@@ -8884,8 +8918,20 @@ function MakeInspectableBridgeServiceDefinition(options) {
|
|
|
8884
8918
|
// onclose will fire after onerror, which handles reconnection.
|
|
8885
8919
|
};
|
|
8886
8920
|
}
|
|
8921
|
+
function disconnect() {
|
|
8922
|
+
if (reconnectTimer !== null) {
|
|
8923
|
+
clearTimeout(reconnectTimer);
|
|
8924
|
+
reconnectTimer = null;
|
|
8925
|
+
}
|
|
8926
|
+
if (ws) {
|
|
8927
|
+
ws.onclose = null;
|
|
8928
|
+
ws.close();
|
|
8929
|
+
ws = null;
|
|
8930
|
+
}
|
|
8931
|
+
setConnected(false);
|
|
8932
|
+
}
|
|
8887
8933
|
function scheduleReconnect() {
|
|
8888
|
-
if (disposed || reconnectTimer !== null) {
|
|
8934
|
+
if (disposed || !enabled || reconnectTimer !== null) {
|
|
8889
8935
|
return;
|
|
8890
8936
|
}
|
|
8891
8937
|
reconnectTimer = setTimeout(() => {
|
|
@@ -8908,6 +8954,14 @@ function MakeInspectableBridgeServiceDefinition(options) {
|
|
|
8908
8954
|
});
|
|
8909
8955
|
break;
|
|
8910
8956
|
}
|
|
8957
|
+
case "getInfo": {
|
|
8958
|
+
sendToBridge({
|
|
8959
|
+
type: "infoResponse",
|
|
8960
|
+
requestId: message.requestId,
|
|
8961
|
+
name: options.name,
|
|
8962
|
+
});
|
|
8963
|
+
break;
|
|
8964
|
+
}
|
|
8911
8965
|
case "execCommand": {
|
|
8912
8966
|
const command = commands.get(message.commandId);
|
|
8913
8967
|
if (!command) {
|
|
@@ -8937,8 +8991,9 @@ function MakeInspectableBridgeServiceDefinition(options) {
|
|
|
8937
8991
|
}
|
|
8938
8992
|
}
|
|
8939
8993
|
}
|
|
8940
|
-
|
|
8941
|
-
|
|
8994
|
+
if (enabled) {
|
|
8995
|
+
connect();
|
|
8996
|
+
}
|
|
8942
8997
|
const registry = {
|
|
8943
8998
|
addCommand(descriptor) {
|
|
8944
8999
|
if (commands.has(descriptor.id)) {
|
|
@@ -8951,24 +9006,31 @@ function MakeInspectableBridgeServiceDefinition(options) {
|
|
|
8951
9006
|
},
|
|
8952
9007
|
};
|
|
8953
9008
|
},
|
|
9009
|
+
get isEnabled() {
|
|
9010
|
+
return enabled;
|
|
9011
|
+
},
|
|
9012
|
+
set isEnabled(value) {
|
|
9013
|
+
if (enabled !== value) {
|
|
9014
|
+
enabled = value;
|
|
9015
|
+
if (enabled) {
|
|
9016
|
+
connect();
|
|
9017
|
+
}
|
|
9018
|
+
else {
|
|
9019
|
+
disconnect();
|
|
9020
|
+
}
|
|
9021
|
+
notifyStatusChanged();
|
|
9022
|
+
}
|
|
9023
|
+
},
|
|
8954
9024
|
get isConnected() {
|
|
8955
9025
|
return connected;
|
|
8956
9026
|
},
|
|
8957
9027
|
onConnectionStatusChanged,
|
|
8958
9028
|
dispose: () => {
|
|
8959
9029
|
disposed = true;
|
|
8960
|
-
|
|
8961
|
-
|
|
8962
|
-
reconnectTimer = null;
|
|
8963
|
-
}
|
|
9030
|
+
enabled = false;
|
|
9031
|
+
disconnect();
|
|
8964
9032
|
commands.clear();
|
|
8965
|
-
setConnected(false);
|
|
8966
9033
|
onConnectionStatusChanged.clear();
|
|
8967
|
-
if (ws) {
|
|
8968
|
-
ws.onclose = null;
|
|
8969
|
-
ws.close();
|
|
8970
|
-
ws = null;
|
|
8971
|
-
}
|
|
8972
9034
|
},
|
|
8973
9035
|
};
|
|
8974
9036
|
return registry;
|
|
@@ -9377,11 +9439,11 @@ const InspectableStates = new Map();
|
|
|
9377
9439
|
function _StartInspectable(scene, options) {
|
|
9378
9440
|
let state = InspectableStates.get(scene);
|
|
9379
9441
|
if (!state) {
|
|
9380
|
-
const port = options?.port ?? DefaultPort;
|
|
9381
|
-
const name = options?.name ?? (typeof document !== "undefined" ? document.title : "Babylon.js Scene");
|
|
9382
9442
|
const serviceContainer = new ServiceContainer("InspectableContainer");
|
|
9443
|
+
let fullyDisposed = false;
|
|
9383
9444
|
const fullyDispose = () => {
|
|
9384
9445
|
InspectableStates.delete(scene);
|
|
9446
|
+
fullyDisposed = true;
|
|
9385
9447
|
serviceContainer.dispose();
|
|
9386
9448
|
sceneDisposeObserver.remove();
|
|
9387
9449
|
};
|
|
@@ -9396,12 +9458,18 @@ function _StartInspectable(scene, options) {
|
|
|
9396
9458
|
};
|
|
9397
9459
|
const readyPromise = (async () => {
|
|
9398
9460
|
await serviceContainer.addServicesAsync(sceneContextServiceDefinition, MakeInspectableBridgeServiceDefinition({
|
|
9399
|
-
port,
|
|
9400
|
-
name
|
|
9461
|
+
port: options?.port ?? DefaultPort,
|
|
9462
|
+
get name() {
|
|
9463
|
+
return options?.name ?? (typeof document !== "undefined" ? document.title : "Babylon.js Scene");
|
|
9464
|
+
},
|
|
9465
|
+
autoStart: options?.autoStart ?? false,
|
|
9401
9466
|
}), EntityQueryServiceDefinition, ScreenshotCommandServiceDefinition, ShaderCommandServiceDefinition, StatsCommandServiceDefinition, PerfTraceCommandServiceDefinition);
|
|
9402
9467
|
})();
|
|
9403
9468
|
state = {
|
|
9404
9469
|
refCount: 0,
|
|
9470
|
+
get fullyDisposed() {
|
|
9471
|
+
return fullyDisposed;
|
|
9472
|
+
},
|
|
9405
9473
|
serviceContainer,
|
|
9406
9474
|
sceneDisposeObserver: { remove: () => { } },
|
|
9407
9475
|
fullyDispose,
|
|
@@ -9454,7 +9522,7 @@ function _StartInspectable(scene, options) {
|
|
|
9454
9522
|
let disposed = false;
|
|
9455
9523
|
const token = {
|
|
9456
9524
|
get isDisposed() {
|
|
9457
|
-
return disposed;
|
|
9525
|
+
return disposed || owningState.fullyDisposed;
|
|
9458
9526
|
},
|
|
9459
9527
|
get serviceContainer() {
|
|
9460
9528
|
return serviceContainer;
|
|
@@ -9530,7 +9598,7 @@ const ColorSliders = ({ color, onSliderChange }) => (jsxs(Fragment, { children:
|
|
|
9530
9598
|
const Color3PropertyLine = ColorPropertyLine;
|
|
9531
9599
|
const Color4PropertyLine = ColorPropertyLine;
|
|
9532
9600
|
|
|
9533
|
-
const useStyles$
|
|
9601
|
+
const useStyles$G = makeStyles({
|
|
9534
9602
|
uniformWidth: {
|
|
9535
9603
|
...UniformWidthStyling,
|
|
9536
9604
|
},
|
|
@@ -9542,7 +9610,7 @@ const useStyles$F = makeStyles({
|
|
|
9542
9610
|
*/
|
|
9543
9611
|
const TextInputPropertyLine = (props) => {
|
|
9544
9612
|
TextInputPropertyLine.displayName = "TextInputPropertyLine";
|
|
9545
|
-
const classes = useStyles$
|
|
9613
|
+
const classes = useStyles$G();
|
|
9546
9614
|
return (jsx(PropertyLine, { ...props, children: jsx(TextInput, { ...props, className: mergeClasses(classes.uniformWidth, props.className) }) }));
|
|
9547
9615
|
};
|
|
9548
9616
|
/**
|
|
@@ -9553,7 +9621,7 @@ const TextInputPropertyLine = (props) => {
|
|
|
9553
9621
|
*/
|
|
9554
9622
|
const NumberInputPropertyLine = (props) => {
|
|
9555
9623
|
NumberInputPropertyLine.displayName = "NumberInputPropertyLine";
|
|
9556
|
-
const classes = useStyles$
|
|
9624
|
+
const classes = useStyles$G();
|
|
9557
9625
|
return (jsx(PropertyLine, { ...props, children: jsx(SpinButton, { ...props, className: mergeClasses(classes.uniformWidth, props.className) }) }));
|
|
9558
9626
|
};
|
|
9559
9627
|
|
|
@@ -9684,6 +9752,14 @@ const LegacyInspectableObjectPropertiesServiceDefinition = {
|
|
|
9684
9752
|
},
|
|
9685
9753
|
};
|
|
9686
9754
|
|
|
9755
|
+
const DocUrl = "https://www.npmjs.com/package/@babylonjs/inspector#inspector-cli";
|
|
9756
|
+
const useStyles$F = makeStyles({
|
|
9757
|
+
tooltipContent: {
|
|
9758
|
+
display: "flex",
|
|
9759
|
+
flexDirection: "column",
|
|
9760
|
+
gap: tokens.spacingVerticalXS,
|
|
9761
|
+
},
|
|
9762
|
+
});
|
|
9687
9763
|
const CliConnectionStatusServiceDefinition = {
|
|
9688
9764
|
friendlyName: "CLI Connection Status",
|
|
9689
9765
|
consumes: [ShellServiceIdentity, CliConnectionStatusIdentity],
|
|
@@ -9695,9 +9771,22 @@ const CliConnectionStatusServiceDefinition = {
|
|
|
9695
9771
|
teachingMoment: false,
|
|
9696
9772
|
order: 0 /* DefaultToolbarItemOrder.CliStatus */,
|
|
9697
9773
|
component: () => {
|
|
9774
|
+
const classes = useStyles$F();
|
|
9775
|
+
const isEnabled = useObservableState(() => cliConnectionStatus.isEnabled, cliConnectionStatus.onConnectionStatusChanged);
|
|
9698
9776
|
const isConnected = useObservableState(() => cliConnectionStatus.isConnected, cliConnectionStatus.onConnectionStatusChanged);
|
|
9699
9777
|
const { showToast } = useToast();
|
|
9700
9778
|
const isFirstRender = useRef(true);
|
|
9779
|
+
const [connectingIconToggle, setConnectingIconToggle] = useState(false);
|
|
9780
|
+
const connecting = isEnabled && !isConnected;
|
|
9781
|
+
useEffect(() => {
|
|
9782
|
+
if (!connecting) {
|
|
9783
|
+
return;
|
|
9784
|
+
}
|
|
9785
|
+
const interval = setInterval(() => {
|
|
9786
|
+
setConnectingIconToggle((prev) => !prev);
|
|
9787
|
+
}, 700);
|
|
9788
|
+
return () => clearInterval(interval);
|
|
9789
|
+
}, [connecting]);
|
|
9701
9790
|
useEffect(() => {
|
|
9702
9791
|
if (isFirstRender.current) {
|
|
9703
9792
|
isFirstRender.current = false;
|
|
@@ -9710,8 +9799,25 @@ const CliConnectionStatusServiceDefinition = {
|
|
|
9710
9799
|
showToast("Inspector bridge disconnected.", { intent: "warning" });
|
|
9711
9800
|
}
|
|
9712
9801
|
}, [isConnected, showToast]);
|
|
9713
|
-
|
|
9714
|
-
|
|
9802
|
+
let icon;
|
|
9803
|
+
let statusText;
|
|
9804
|
+
if (!isEnabled) {
|
|
9805
|
+
icon = jsx(PlugDisconnectedRegular, { color: tokens.colorNeutralForeground4 });
|
|
9806
|
+
statusText = "Inspector CLI bridge disabled — click to connect";
|
|
9807
|
+
}
|
|
9808
|
+
else if (!isConnected) {
|
|
9809
|
+
icon = connectingIconToggle ? (jsx(PlugConnectedRegular, { color: tokens.colorPaletteYellowForeground2 })) : (jsx(PlugDisconnectedRegular, { color: tokens.colorPaletteYellowForeground2 }));
|
|
9810
|
+
statusText = "Connecting to Inspector CLI bridge — click to disconnect";
|
|
9811
|
+
}
|
|
9812
|
+
else {
|
|
9813
|
+
icon = jsx(PlugConnectedCheckmarkRegular, { color: tokens.colorPaletteGreenForeground2 });
|
|
9814
|
+
statusText = "Connected to Inspector CLI bridge — click to disconnect";
|
|
9815
|
+
}
|
|
9816
|
+
const tooltipContent = (jsxs("div", { className: classes.tooltipContent, children: [jsx(Body1, { children: statusText }), jsx(Link, { url: DocUrl, value: "Inspector CLI documentation" })] }));
|
|
9817
|
+
// Using raw Fluent Button for custom icon coloring per connection state.
|
|
9818
|
+
return (jsx(Tooltip, { content: tooltipContent, children: jsx(Button$1, { appearance: "subtle", "aria-label": statusText, icon: icon, onClick: () => {
|
|
9819
|
+
cliConnectionStatus.isEnabled = !cliConnectionStatus.isEnabled;
|
|
9820
|
+
} }) }));
|
|
9715
9821
|
},
|
|
9716
9822
|
});
|
|
9717
9823
|
},
|
|
@@ -18079,7 +18185,7 @@ const PhysicsPropertiesServiceDefinition = {
|
|
|
18079
18185
|
*/
|
|
18080
18186
|
const PostProcessProperties = (props) => {
|
|
18081
18187
|
const { postProcess } = props;
|
|
18082
|
-
return (jsxs(Fragment, { children: [jsx(StringifiedPropertyLine, { label: "Width", description: "The width of the post process", value: postProcess.width, units: "px" }), jsx(StringifiedPropertyLine, { label: "Height", description: "The height of the post process", value: postProcess.height, units: "px" }), jsx(BoundProperty, { component:
|
|
18188
|
+
return (jsxs(Fragment, { children: [jsx(StringifiedPropertyLine, { label: "Width", description: "The width of the post process", value: postProcess.width, units: "px" }), jsx(StringifiedPropertyLine, { label: "Height", description: "The height of the post process", value: postProcess.height, units: "px" }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Auto Clear", target: postProcess, propertyKey: "autoClear" }), postProcess.clearColor && jsx(BoundProperty, { component: Color4PropertyLine, label: "Clear Color", target: postProcess, propertyKey: "clearColor" }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Pixel Perfect", target: postProcess, propertyKey: "enablePixelPerfectMode" }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Fullscreen Viewport", target: postProcess, propertyKey: "forceFullscreenViewport" }), jsx(BoundProperty, { component: SyncedSliderPropertyLine, label: "Samples", target: postProcess, propertyKey: "samples", min: 1, max: 8, step: 1 })] }));
|
|
18083
18189
|
};
|
|
18084
18190
|
|
|
18085
18191
|
const PostProcessPropertiesServiceDefinition = {
|
|
@@ -22727,23 +22833,68 @@ const CoordinateSystemModeOptions = [
|
|
|
22727
22833
|
{ label: "Right Handed", value: GLTFLoaderCoordinateSystemMode.FORCE_RIGHT_HANDED },
|
|
22728
22834
|
];
|
|
22729
22835
|
const GLTFLoaderOptionsTool = ({ loaderOptions }) => {
|
|
22730
|
-
|
|
22836
|
+
const resetLoaderOptions = useCallback(() => {
|
|
22837
|
+
for (const key of Object.keys(loaderOptions)) {
|
|
22838
|
+
loaderOptions[key] = null;
|
|
22839
|
+
}
|
|
22840
|
+
}, [loaderOptions]);
|
|
22841
|
+
return (jsx(PropertyLine, { label: "Loader Options", expandByDefault: false, expandedContent: jsxs(Fragment, { children: [jsx(BoundProperty, { component: SwitchPropertyLine, label: "Always Compute Bounding Box", target: loaderOptions, propertyKey: "alwaysComputeBoundingBox", nullable: true, defaultValue: LoaderOptionDefaults.alwaysComputeBoundingBox }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Always Compute Skeleton Root Node", target: loaderOptions, propertyKey: "alwaysComputeSkeletonRootNode", nullable: true, defaultValue: LoaderOptionDefaults.alwaysComputeSkeletonRootNode }), jsx(BoundProperty, { component: NumberDropdownPropertyLine, label: "Animation Start Mode", options: AnimationStartModeOptions, target: loaderOptions, propertyKey: "animationStartMode", nullable: true, defaultValue: LoaderOptionDefaults.animationStartMode }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Capture Performance Counters", target: loaderOptions, propertyKey: "capturePerformanceCounters", nullable: true, defaultValue: LoaderOptionDefaults.capturePerformanceCounters }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Compile Materials", target: loaderOptions, propertyKey: "compileMaterials", nullable: true, defaultValue: LoaderOptionDefaults.compileMaterials }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Compile Shadow Generators", target: loaderOptions, propertyKey: "compileShadowGenerators", nullable: true, defaultValue: LoaderOptionDefaults.compileShadowGenerators }), jsx(BoundProperty, { component: NumberDropdownPropertyLine, label: "Coordinate System", options: CoordinateSystemModeOptions, target: loaderOptions, propertyKey: "coordinateSystemMode", nullable: true, defaultValue: LoaderOptionDefaults.coordinateSystemMode }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Create Instances", target: loaderOptions, propertyKey: "createInstances", nullable: true, defaultValue: LoaderOptionDefaults.createInstances }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Don't Use Transmission Helper", target: loaderOptions, propertyKey: "dontUseTransmissionHelper", nullable: true, defaultValue: LoaderOptionDefaults.dontUseTransmissionHelper }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Enable Logging", target: loaderOptions, propertyKey: "loggingEnabled", nullable: true, defaultValue: LoaderOptionDefaults.loggingEnabled }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Load All Materials", target: loaderOptions, propertyKey: "loadAllMaterials", nullable: true, defaultValue: LoaderOptionDefaults.loadAllMaterials }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Load Morph Targets", target: loaderOptions, propertyKey: "loadMorphTargets", nullable: true, defaultValue: LoaderOptionDefaults.loadMorphTargets }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Load Node Animations", target: loaderOptions, propertyKey: "loadNodeAnimations", nullable: true, defaultValue: LoaderOptionDefaults.loadNodeAnimations }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Load Only Materials", target: loaderOptions, propertyKey: "loadOnlyMaterials", nullable: true, defaultValue: LoaderOptionDefaults.loadOnlyMaterials }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Load Skins", target: loaderOptions, propertyKey: "loadSkins", nullable: true, defaultValue: LoaderOptionDefaults.loadSkins }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Skip Materials", target: loaderOptions, propertyKey: "skipMaterials", nullable: true, defaultValue: LoaderOptionDefaults.skipMaterials }), jsx(BoundProperty, { component: SyncedSliderPropertyLine, label: "Target FPS", target: loaderOptions, propertyKey: "targetFps", min: 1, max: 120, step: 1, nullable: true, defaultValue: LoaderOptionDefaults.targetFps }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Transparency As Coverage", target: loaderOptions, propertyKey: "transparencyAsCoverage", nullable: true, defaultValue: LoaderOptionDefaults.transparencyAsCoverage }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Use Clip Plane", target: loaderOptions, propertyKey: "useClipPlane", nullable: true, defaultValue: LoaderOptionDefaults.useClipPlane }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Use glTF Texture Names", target: loaderOptions, propertyKey: "useGltfTextureNames", nullable: true, defaultValue: LoaderOptionDefaults.useGltfTextureNames }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Use OpenPBR", target: loaderOptions, propertyKey: "useOpenPBR", nullable: true, defaultValue: LoaderOptionDefaults.useOpenPBR }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Use Range Requests", target: loaderOptions, propertyKey: "useRangeRequests", nullable: true, defaultValue: LoaderOptionDefaults.useRangeRequests }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Use sRGB Buffers", target: loaderOptions, propertyKey: "useSRGBBuffers", nullable: true, defaultValue: LoaderOptionDefaults.useSRGBBuffers }), jsx(ButtonLine, { label: "Reset to Defaults", icon: ArrowResetRegular, onClick: resetLoaderOptions })] }) }));
|
|
22731
22842
|
};
|
|
22732
22843
|
const GLTFExtensionOptionsTool = ({ extensionOptions }) => {
|
|
22733
|
-
|
|
22734
|
-
|
|
22735
|
-
|
|
22736
|
-
|
|
22737
|
-
|
|
22738
|
-
|
|
22844
|
+
const resetExtensionOptions = useCallback(() => {
|
|
22845
|
+
for (const options of Object.values(extensionOptions)) {
|
|
22846
|
+
for (const key of Object.keys(options)) {
|
|
22847
|
+
options[key] = null;
|
|
22848
|
+
}
|
|
22849
|
+
}
|
|
22850
|
+
}, [extensionOptions]);
|
|
22851
|
+
return (jsx(PropertyLine, { label: "Extension Options", expandByDefault: false, expandedContent: jsxs(Fragment, { children: [Object.entries(extensionOptions)
|
|
22852
|
+
.sort(([a], [b]) => a.localeCompare(b))
|
|
22853
|
+
.map(([extensionName, options]) => {
|
|
22854
|
+
return (jsx(BoundProperty, { component: SwitchPropertyLine, label: extensionName, target: options, propertyKey: "enabled", nullable: true, defaultValue: true, expandedContent: (extensionName === "MSFT_lod" && (jsx(BoundProperty, { component: SyncedSliderPropertyLine, label: "Maximum LODs", target: extensionOptions[extensionName], propertyKey: "maxLODsToLoad", min: 1, max: 10, step: 1, nullable: true, defaultValue: ExtensionOptionDefaults.MSFT_lod.maxLODsToLoad }, extensionName + "_maxLODsToLoad"))) ||
|
|
22855
|
+
undefined }, extensionName));
|
|
22856
|
+
}), jsx(ButtonLine, { label: "Reset to Defaults", icon: ArrowResetRegular, onClick: resetExtensionOptions })] }) }));
|
|
22739
22857
|
};
|
|
22740
22858
|
|
|
22859
|
+
const LoaderOptionsSetting = {
|
|
22860
|
+
key: "glTFLoaderOptions",
|
|
22861
|
+
defaultValue: {},
|
|
22862
|
+
};
|
|
22863
|
+
const ExtensionOptionsSetting = {
|
|
22864
|
+
key: "glTFExtensionOptions",
|
|
22865
|
+
defaultValue: {},
|
|
22866
|
+
};
|
|
22867
|
+
function CreatePersistingProxy(target, settingsStore, descriptor) {
|
|
22868
|
+
return new Proxy(target, {
|
|
22869
|
+
set(obj, prop, value) {
|
|
22870
|
+
const result = Reflect.set(obj, prop, value);
|
|
22871
|
+
settingsStore.writeSetting(descriptor, { ...obj });
|
|
22872
|
+
return result;
|
|
22873
|
+
},
|
|
22874
|
+
});
|
|
22875
|
+
}
|
|
22876
|
+
function HasNonNullValues(obj) {
|
|
22877
|
+
return Object.values(obj).some((v) => v !== null);
|
|
22878
|
+
}
|
|
22879
|
+
const OverridesWarning = (props) => {
|
|
22880
|
+
const { loaderOptions, extensionOptions } = props;
|
|
22881
|
+
useSetting(LoaderOptionsSetting);
|
|
22882
|
+
useSetting(ExtensionOptionsSetting);
|
|
22883
|
+
const hasLoaderOverrides = HasNonNullValues(loaderOptions);
|
|
22884
|
+
const hasExtensionOverrides = Object.values(extensionOptions).some((opts) => HasNonNullValues(opts));
|
|
22885
|
+
return (jsx(Collapse, { visible: hasLoaderOverrides || hasExtensionOverrides, children: jsx(MessageBar, { intent: "warning", message: "Loader option overrides are enabled and will persist across refreshes until disabled or reset." }) }));
|
|
22886
|
+
};
|
|
22741
22887
|
const GLTFLoaderOptionsServiceDefinition = {
|
|
22742
22888
|
friendlyName: "GLTF Loader Options",
|
|
22743
|
-
consumes: [ToolsServiceIdentity],
|
|
22744
|
-
factory: (toolsService) => {
|
|
22889
|
+
consumes: [ToolsServiceIdentity, SettingsStoreIdentity, ToastServiceIdentity],
|
|
22890
|
+
factory: (toolsService, settingsStore, toastService) => {
|
|
22745
22891
|
// Current loader options with nullable properties (null means "don't override the options coming in with load calls")
|
|
22746
|
-
|
|
22892
|
+
let currentLoaderOptions = Object.fromEntries(Object.keys(LoaderOptionDefaults).map((key) => [key, null]));
|
|
22893
|
+
// Hydrate loader options from persisted settings
|
|
22894
|
+
const persistedLoaderOptions = settingsStore.readSetting(LoaderOptionsSetting);
|
|
22895
|
+
Object.assign(currentLoaderOptions, persistedLoaderOptions);
|
|
22896
|
+
// Wrap in a proxy so property writes from the UI are automatically persisted
|
|
22897
|
+
currentLoaderOptions = CreatePersistingProxy(currentLoaderOptions, settingsStore, LoaderOptionsSetting);
|
|
22747
22898
|
// Build extension options dynamically from the registered extensions.
|
|
22748
22899
|
// Every extension gets an 'enabled' toggle; extensions in ExtensionOptionDefaults also get their extra properties.
|
|
22749
22900
|
const currentExtensionOptions = {};
|
|
@@ -22752,22 +22903,50 @@ const GLTFLoaderOptionsServiceDefinition = {
|
|
|
22752
22903
|
const extraNulls = defaults ? Object.fromEntries(Object.keys(defaults).map((key) => [key, null])) : {};
|
|
22753
22904
|
currentExtensionOptions[extName] = { enabled: null, ...extraNulls };
|
|
22754
22905
|
}
|
|
22906
|
+
// Hydrate extension options from persisted settings, only for extensions that are still registered
|
|
22907
|
+
const persistedExtensionOptions = settingsStore.readSetting(ExtensionOptionsSetting);
|
|
22908
|
+
for (const [extName, persistedOptions] of Object.entries(persistedExtensionOptions)) {
|
|
22909
|
+
if (currentExtensionOptions[extName] && persistedOptions) {
|
|
22910
|
+
Object.assign(currentExtensionOptions[extName], persistedOptions);
|
|
22911
|
+
}
|
|
22912
|
+
}
|
|
22913
|
+
// Wrap each extension's options object in a proxy that persists the full extension options map on write
|
|
22914
|
+
for (const extName of Object.keys(currentExtensionOptions)) {
|
|
22915
|
+
currentExtensionOptions[extName] = new Proxy(currentExtensionOptions[extName], {
|
|
22916
|
+
set(obj, prop, value) {
|
|
22917
|
+
const result = Reflect.set(obj, prop, value);
|
|
22918
|
+
settingsStore.writeSetting(ExtensionOptionsSetting, { ...currentExtensionOptions });
|
|
22919
|
+
return result;
|
|
22920
|
+
},
|
|
22921
|
+
});
|
|
22922
|
+
}
|
|
22755
22923
|
// Subscribe to plugin activation
|
|
22756
22924
|
const pluginObserver = SceneLoader.OnPluginActivatedObservable.add((plugin) => {
|
|
22757
22925
|
if (plugin.name === "gltf") {
|
|
22758
22926
|
const loader = plugin;
|
|
22759
22927
|
// Apply loader settings (filter out null values to not override options coming in with load calls)
|
|
22760
22928
|
const nonNullLoaderOptions = Object.fromEntries(Object.entries(currentLoaderOptions).filter(([_, v]) => v !== null));
|
|
22929
|
+
const hasLoaderOverrides = Object.keys(nonNullLoaderOptions).length > 0;
|
|
22761
22930
|
Object.assign(loader, nonNullLoaderOptions);
|
|
22931
|
+
let hasExtensionOverrides = false;
|
|
22762
22932
|
// Subscribe to extension loading
|
|
22763
22933
|
loader.onExtensionLoadedObservable.add((extension) => {
|
|
22764
22934
|
const extensionOptions = currentExtensionOptions[extension.name];
|
|
22765
22935
|
if (extensionOptions) {
|
|
22766
22936
|
// Apply extension settings (filter out null values to not override options coming in with load calls)
|
|
22767
22937
|
const nonNullExtOptions = Object.fromEntries(Object.entries(extensionOptions).filter(([_, v]) => v !== null));
|
|
22938
|
+
if (Object.keys(nonNullExtOptions).length > 0) {
|
|
22939
|
+
hasExtensionOverrides = true;
|
|
22940
|
+
}
|
|
22768
22941
|
Object.assign(extension, nonNullExtOptions);
|
|
22769
22942
|
}
|
|
22770
22943
|
});
|
|
22944
|
+
// Show a toast after all extensions have loaded if any overrides were applied
|
|
22945
|
+
loader.onCompleteObservable.addOnce(() => {
|
|
22946
|
+
if (hasLoaderOverrides || hasExtensionOverrides) {
|
|
22947
|
+
toastService.showToast("Applied glTF loader option overrides");
|
|
22948
|
+
}
|
|
22949
|
+
});
|
|
22771
22950
|
}
|
|
22772
22951
|
});
|
|
22773
22952
|
const loaderToolsRegistration = toolsService.addSectionContent({
|
|
@@ -22775,7 +22954,7 @@ const GLTFLoaderOptionsServiceDefinition = {
|
|
|
22775
22954
|
section: "GLTF Loader",
|
|
22776
22955
|
order: 50,
|
|
22777
22956
|
component: () => {
|
|
22778
|
-
return (jsxs(Fragment, { children: [jsx(MessageBar, { intent: "info", message: "Reload the file for changes to take effect" }), jsx(GLTFLoaderOptionsTool, { loaderOptions: currentLoaderOptions }), jsx(GLTFExtensionOptionsTool, { extensionOptions: currentExtensionOptions })] }));
|
|
22957
|
+
return (jsxs(Fragment, { children: [jsx(MessageBar, { intent: "info", message: "Reload the file for changes to take effect" }), jsx(OverridesWarning, { loaderOptions: currentLoaderOptions, extensionOptions: currentExtensionOptions }), jsx(GLTFLoaderOptionsTool, { loaderOptions: currentLoaderOptions }), jsx(GLTFExtensionOptionsTool, { extensionOptions: currentExtensionOptions })] }));
|
|
22779
22958
|
},
|
|
22780
22959
|
});
|
|
22781
22960
|
return {
|
|
@@ -24073,4 +24252,4 @@ const TextAreaPropertyLine = (props) => {
|
|
|
24073
24252
|
AttachDebugLayer();
|
|
24074
24253
|
|
|
24075
24254
|
export { GizmoServiceIdentity as $, Accordion as A, Button as B, CheckboxPropertyLine as C, ColorPickerPopup as D, ColorStepGradientComponent as E, ComboBox as F, ComboBoxPropertyLine as G, ConstructorFactory as H, ConvertOptions as I, DebugServiceIdentity as J, DetachDebugLayer as K, Link as L, MessageBar as M, NumberInputPropertyLine as N, DraggableLine as O, Popover as P, Dropdown as Q, EntitySelector as R, ShellServiceIdentity as S, TextInputPropertyLine as T, ErrorBoundary as U, Vector3PropertyLine as V, ExtensibleAccordion as W, FactorGradientComponent as X, FactorGradientList as Y, FileUploadLine as Z, GetPropertyDescriptor as _, useToast as a, ToastProvider as a$, HexPropertyLine as a0, InfoLabel as a1, InputHexField as a2, InputHsvField as a3, InspectableCommandRegistryIdentity as a4, Inspector as a5, InterceptFunction as a6, InterceptProperty as a7, IsPropertyReadonly as a8, LineContainer as a9, SelectionServiceDefinition as aA, SettingsServiceIdentity as aB, SettingsStore as aC, SettingsStoreIdentity as aD, ShowInspector as aE, SidePaneContainer as aF, SkeletonSelector as aG, Slider as aH, SpinButton as aI, StartInspectable as aJ, StatsServiceIdentity as aK, StringDropdown as aL, StringDropdownPropertyLine as aM, StringifiedPropertyLine as aN, Switch as aO, SwitchPropertyLine as aP, SyncedSliderInput as aQ, SyncedSliderPropertyLine as aR, TeachingMoment as aS, TextAreaPropertyLine as aT, TextInput as aU, TextPropertyLine as aV, Textarea as aW, TextureSelector as aX, TextureUpload as aY, Theme as aZ, ThemeServiceIdentity as a_, LinkPropertyLine as aa, LinkToEntityPropertyLine as ab, List as ac, MakeDialogTeachingMoment as ad, MakeLazyComponent as ae, MakeModularTool as af, MakePopoverTeachingMoment as ag, MakePropertyHook as ah, MakeTeachingMoment as ai, MaterialSelector as aj, NodeSelector as ak, NumberDropdown as al, NumberDropdownPropertyLine as am, ObservableCollection as an, Pane as ao, PlaceholderPropertyLine as ap, PositionedPopover as aq, PropertiesServiceIdentity as ar, Property as as, PropertyContext as at, PropertyLine as au, QuaternionPropertyLine as av, RotationVectorPropertyLine as aw, SceneExplorerServiceIdentity as ax, SearchBar as ay, SearchBox as az, useInterceptObservable as b, ToggleButton as b0, Tooltip as b1, UploadButton as b2, Vector2PropertyLine as b3, Vector4PropertyLine as b4, WatcherServiceIdentity as b5, useAngleConverters as b6, useAsyncResource as b7, useColor3Property as b8, useColor4Property as b9, useEventListener as ba, useEventfulState as bb, useKeyListener as bc, useKeyState as bd, useObservableCollection as be, useOrderedObservableCollection as bf, usePollingObservable as bg, usePropertyChangedNotifier as bh, useQuaternionProperty as bi, useResource as bj, useTheme as bk, useThemeMode as bl, useVector3Property as bm, LinkToEntity as c, SpinButtonPropertyLine as d, useProperty as e, SceneContextIdentity as f, SelectionServiceIdentity as g, useObservableState as h, AccordionSection as i, ButtonLine as j, ToolsServiceIdentity as k, AccordionSectionItem as l, AttachDebugLayer as m, BooleanBadgePropertyLine as n, BoundProperty as o, BuiltInsExtensionFeed as p, Checkbox as q, ChildWindow as r, Collapse as s, Color3GradientComponent as t, useExtensionManager as u, Color3GradientList as v, Color3PropertyLine as w, Color4GradientComponent as x, Color4GradientList as y, Color4PropertyLine as z };
|
|
24076
|
-
//# sourceMappingURL=index-
|
|
24255
|
+
//# sourceMappingURL=index-BaFR1FRV.js.map
|