@babylonjs/inspector 8.30.5-preview → 8.31.0-preview
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/lib/{captureService-BApVw0DN.js → captureService-CuhjVz1y.js} +2 -1
- package/lib/{captureService-BApVw0DN.js.map → captureService-CuhjVz1y.js.map} +1 -1
- package/lib/{exportService-D-dQNOY7.js → exportService-Cu9CXW_A.js} +2 -1
- package/lib/{exportService-D-dQNOY7.js.map → exportService-Cu9CXW_A.js.map} +1 -1
- package/lib/{importService-Bnx5hsFQ.js → importService-BETG4FuQ.js} +2 -1
- package/lib/{importService-Bnx5hsFQ.js.map → importService-BETG4FuQ.js.map} +1 -1
- package/lib/index.js +280 -122
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -3,9 +3,9 @@ import { useMemo, useEffect, useState, useRef, useCallback, forwardRef, createCo
|
|
|
3
3
|
import { Color3, Color4 } from '@babylonjs/core/Maths/math.color.js';
|
|
4
4
|
import { Vector3, Quaternion, Matrix, Vector2, Vector4, TmpVectors } from '@babylonjs/core/Maths/math.vector.js';
|
|
5
5
|
import { Observable } from '@babylonjs/core/Misc/observable.js';
|
|
6
|
-
import { makeStyles, ToggleButton as ToggleButton$1, Button as Button$1, tokens, Link, InfoLabel as InfoLabel$1,
|
|
6
|
+
import { makeStyles, ToggleButton as ToggleButton$1, Button as Button$1, tokens, Link, InfoLabel as InfoLabel$1, Body1Strong, Checkbox as Checkbox$1, Body1, Accordion as Accordion$1, AccordionItem, AccordionHeader, Subtitle2Stronger, AccordionPanel, Divider, mergeClasses, TeachingPopover, TeachingPopoverSurface, TeachingPopoverHeader, TeachingPopoverBody, createLightTheme, createDarkTheme, FluentProvider, Toolbar as Toolbar$1, Tooltip, ToolbarRadioButton, SearchBox as SearchBox$1, FlatTree, FlatTreeItem, TreeItemLayout, Menu, MenuTrigger, MenuPopover, MenuList, MenuItem, Switch as Switch$1, PresenceBadge, Spinner, Dialog, DialogTrigger, DialogSurface, DialogBody, DialogTitle, TabList, Tab, DialogContent, SplitButton, MenuItemRadio, DialogActions, List as List$1, ListItem, useId, Input, SpinButton as SpinButton$1, Slider, MessageBar as MessageBar$1, MessageBarBody, MessageBarTitle, Badge, Dropdown as Dropdown$1, Option, Popover, PopoverTrigger, ColorSwatch, PopoverSurface, ColorPicker, ColorArea, ColorSlider, AlphaSlider, Textarea as Textarea$1, ToolbarButton, useComboboxFilter, Combobox, Field } from '@fluentui/react-components';
|
|
7
7
|
export { Link } from '@fluentui/react-components';
|
|
8
|
-
import { ChevronCircleRight20Regular, ChevronCircleDown20Regular, CopyRegular, PanelLeftExpandRegular, PanelLeftContractRegular, PanelRightExpandRegular, PanelRightContractRegular, DocumentTextRegular, FilterRegular,
|
|
8
|
+
import { ChevronCircleRight20Regular, ChevronCircleDown20Regular, CopyRegular, PanelLeftExpandRegular, PanelLeftContractRegular, PanelRightExpandRegular, PanelRightContractRegular, DocumentTextRegular, createFluentIcon, FilterRegular, GlobeRegular, ArrowExpandAllRegular, CubeTreeRegular, BugRegular, SettingsRegular, ArrowUploadRegular, DataBarHorizontalRegular, WrenchRegular, AppsAddInRegular, DismissRegular, WeatherSunnyRegular, WeatherMoonRegular, ErrorCircleRegular, ArrowRotateClockwiseRegular, ArrowExpandRegular, SelectObjectRegular, CubeRegular, SaveRegular, ArrowUndoRegular, BracesRegular, BracesDismiss16Regular, DeleteRegular, EyeOffFilled, EyeFilled, ArrowMoveFilled, StopFilled, PlayFilled, StackRegular, FilmstripRegular, PauseFilled, WeatherSunnyLowFilled, LayerRegular, FrameRegular, PlayRegular, AppGenericRegular, MyLocationRegular, CameraRegular, LightbulbRegular, BorderOutsideRegular, BorderNoneRegular, EyeRegular, EyeOffRegular, VideoFilled, VideoRegular, FlashlightRegular, FlashlightOffRegular, DropRegular, BlurRegular, PipelineRegular, PersonWalkingRegular, DataLineRegular, PersonSquareRegular, LayerDiagonalPersonRegular, ImageEditRegular, ImageRegular, TargetRegular, DeleteFilled } from '@fluentui/react-icons';
|
|
9
9
|
import { Collapse as Collapse$1 } from '@fluentui/react-motion-components-preview';
|
|
10
10
|
import '@babylonjs/core/Misc/typeStore.js';
|
|
11
11
|
import { useLocalStorage, useTernaryDarkMode } from 'usehooks-ts';
|
|
@@ -99,6 +99,7 @@ import { MultiRenderTarget } from '@babylonjs/core/Materials/Textures/multiRende
|
|
|
99
99
|
import { RenderTargetTexture } from '@babylonjs/core/Materials/Textures/renderTargetTexture.js';
|
|
100
100
|
import { ThinTexture } from '@babylonjs/core/Materials/Textures/thinTexture.js';
|
|
101
101
|
import { WhenTextureReadyAsync, GetTextureDataAsync } from '@babylonjs/core/Misc/textureTools.js';
|
|
102
|
+
import '@babylonjs/core/Rendering/boundingBoxRenderer.js';
|
|
102
103
|
import '@babylonjs/core/PostProcesses/RenderPipeline/postProcessRenderPipelineManagerSceneComponent.js';
|
|
103
104
|
import '@babylonjs/core/Sprites/spriteSceneComponent.js';
|
|
104
105
|
import { DynamicTexture } from '@babylonjs/core/Materials/Textures/dynamicTexture.js';
|
|
@@ -674,9 +675,10 @@ const CustomTokens = {
|
|
|
674
675
|
sliderMaxWidth: "80px",
|
|
675
676
|
rightAlignOffset: "-8px",
|
|
676
677
|
};
|
|
677
|
-
const UniformWidthStyling = { width: CustomTokens.inputWidth,
|
|
678
|
+
const UniformWidthStyling = { width: CustomTokens.inputWidth, boxSizing: "border-box" };
|
|
678
679
|
const useInputStyles$1 = makeStyles({
|
|
679
680
|
input: UniformWidthStyling,
|
|
681
|
+
inputSlot: { textAlign: "right" },
|
|
680
682
|
invalid: { backgroundColor: tokens.colorPaletteRedBackground2 },
|
|
681
683
|
container: {
|
|
682
684
|
flex: 1,
|
|
@@ -711,22 +713,26 @@ const usePropertyLineStyles = makeStyles({
|
|
|
711
713
|
justifyContent: "flex-start",
|
|
712
714
|
width: "100%",
|
|
713
715
|
},
|
|
714
|
-
|
|
716
|
+
infoLabel: {
|
|
717
|
+
display: "flex",
|
|
715
718
|
flex: "1 1 0", // grow=1, shrink =1, basis = 0 initial size before
|
|
716
719
|
minWidth: CustomTokens.labelMinWidth,
|
|
717
720
|
textAlign: "left",
|
|
718
|
-
|
|
719
|
-
|
|
721
|
+
},
|
|
722
|
+
labelSlot: {
|
|
723
|
+
display: "flex",
|
|
724
|
+
minWidth: 0,
|
|
720
725
|
},
|
|
721
726
|
labelText: {
|
|
722
727
|
whiteSpace: "nowrap",
|
|
728
|
+
overflow: "hidden",
|
|
729
|
+
textOverflow: "ellipsis",
|
|
723
730
|
},
|
|
724
731
|
rightContent: {
|
|
725
732
|
flex: "0 1 auto",
|
|
726
733
|
display: "flex",
|
|
727
734
|
alignItems: "center",
|
|
728
735
|
justifyContent: "flex-end",
|
|
729
|
-
minWidth: "50%",
|
|
730
736
|
},
|
|
731
737
|
infoPopup: {
|
|
732
738
|
whiteSpace: "normal",
|
|
@@ -760,7 +766,7 @@ const PropertyLine = forwardRef((props, ref) => {
|
|
|
760
766
|
defaultValue: undefined, // Don't pass defaultValue to children as there is no guarantee how this will be used and we can't mix controlled + uncontrolled state
|
|
761
767
|
})
|
|
762
768
|
: children;
|
|
763
|
-
return (jsxs(LineContainer, { ref: ref, children: [jsxs("div", { className: classes.baseLine, children: [jsx(InfoLabel$1, { className: classes.label, info: description ? jsx("div", { className: classes.infoPopup, children: description }) : undefined, title: label, children: jsx(
|
|
769
|
+
return (jsxs(LineContainer, { ref: ref, children: [jsxs("div", { className: classes.baseLine, children: [jsx(InfoLabel$1, { className: classes.infoLabel, label: { className: classes.labelSlot }, info: description ? jsx("div", { className: classes.infoPopup, children: description }) : undefined, title: label, children: jsx(Body1Strong, { className: classes.labelText, children: label }) }), jsxs("div", { className: classes.rightContent, children: [expandedContent && (jsx(ToggleButton, { title: "Expand/Collapse property", appearance: "transparent", checkedIcon: ChevronCircleDown20Regular, uncheckedIcon: ChevronCircleRight20Regular, value: expanded === true, onChange: setExpanded })), nullable && !ignoreNullable && (
|
|
764
770
|
// If this is a nullableProperty and ignoreNullable was not sent, display a checkbox used to toggle null ('checked' means 'non null')
|
|
765
771
|
jsx(Checkbox$1, { checked: !(props.value == null), onChange: (_, data) => {
|
|
766
772
|
if (data.checked) {
|
|
@@ -1342,6 +1348,64 @@ const SelectionServiceDefinition = {
|
|
|
1342
1348
|
},
|
|
1343
1349
|
};
|
|
1344
1350
|
|
|
1351
|
+
const ThemeModeStorageKey = `Babylon/Settings/ThemeMode`;
|
|
1352
|
+
/**
|
|
1353
|
+
* Custom hook to manage the theme mode (system/dark/light).
|
|
1354
|
+
* @returns An object containing the theme mode state and helper functions.
|
|
1355
|
+
*/
|
|
1356
|
+
function useThemeMode() {
|
|
1357
|
+
const { isDarkMode, ternaryDarkMode, setTernaryDarkMode } = useTernaryDarkMode({
|
|
1358
|
+
localStorageKey: ThemeModeStorageKey,
|
|
1359
|
+
});
|
|
1360
|
+
// Make sure there is a stored value initially, even before changing the theme.
|
|
1361
|
+
// This way, other usages of this hook will get the correct initial value.
|
|
1362
|
+
if (!localStorage.getItem(ThemeModeStorageKey)) {
|
|
1363
|
+
SetThemeMode(ternaryDarkMode);
|
|
1364
|
+
}
|
|
1365
|
+
return { isDarkMode, themeMode: ternaryDarkMode, setThemeMode: setTernaryDarkMode };
|
|
1366
|
+
}
|
|
1367
|
+
/**
|
|
1368
|
+
* Sets the theme mode.
|
|
1369
|
+
* @param mode The desired theme mode (system/dark/light).
|
|
1370
|
+
*/
|
|
1371
|
+
function SetThemeMode(mode) {
|
|
1372
|
+
localStorage.setItem(ThemeModeStorageKey, JSON.stringify(mode));
|
|
1373
|
+
}
|
|
1374
|
+
|
|
1375
|
+
/* eslint-disable @typescript-eslint/naming-convention */
|
|
1376
|
+
// Generated from https://react.fluentui.dev/?path=/docs/theme-theme-designer--docs
|
|
1377
|
+
// Key color: #3A94FC
|
|
1378
|
+
const babylonRamp = {
|
|
1379
|
+
10: "#020305",
|
|
1380
|
+
20: "#121721",
|
|
1381
|
+
30: "#1A263A",
|
|
1382
|
+
40: "#1F314F",
|
|
1383
|
+
50: "#243E64",
|
|
1384
|
+
60: "#294B7B",
|
|
1385
|
+
70: "#2D5892",
|
|
1386
|
+
80: "#3166AA",
|
|
1387
|
+
90: "#3473C3",
|
|
1388
|
+
100: "#3782DC",
|
|
1389
|
+
110: "#3990F6",
|
|
1390
|
+
120: "#5A9EFD",
|
|
1391
|
+
130: "#7BACFE",
|
|
1392
|
+
140: "#96BAFF",
|
|
1393
|
+
150: "#AFC9FF",
|
|
1394
|
+
160: "#C6D8FF",
|
|
1395
|
+
};
|
|
1396
|
+
const LightTheme = {
|
|
1397
|
+
...createLightTheme(babylonRamp),
|
|
1398
|
+
};
|
|
1399
|
+
const DarkTheme = {
|
|
1400
|
+
...createDarkTheme(babylonRamp),
|
|
1401
|
+
};
|
|
1402
|
+
|
|
1403
|
+
const Theme = (props) => {
|
|
1404
|
+
const { invert = false, ...rest } = props;
|
|
1405
|
+
const { isDarkMode } = useThemeMode();
|
|
1406
|
+
return (jsx(FluentProvider, { theme: isDarkMode !== invert ? DarkTheme : LightTheme, ...rest, children: props.children }));
|
|
1407
|
+
};
|
|
1408
|
+
|
|
1345
1409
|
const RootComponentServiceIdentity = Symbol("RootComponent");
|
|
1346
1410
|
const ShellServiceIdentity = Symbol("ShellService");
|
|
1347
1411
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
@@ -1361,6 +1425,7 @@ const useStyles$b = makeStyles({
|
|
|
1361
1425
|
display: "flex",
|
|
1362
1426
|
flexDirection: "row",
|
|
1363
1427
|
flex: "0 0 auto",
|
|
1428
|
+
height: "36px",
|
|
1364
1429
|
backgroundColor: tokens.colorNeutralBackground2,
|
|
1365
1430
|
},
|
|
1366
1431
|
bar: {
|
|
@@ -1368,16 +1433,14 @@ const useStyles$b = makeStyles({
|
|
|
1368
1433
|
flex: "1",
|
|
1369
1434
|
height: "32px",
|
|
1370
1435
|
overflow: "hidden",
|
|
1371
|
-
padding: `${tokens.
|
|
1436
|
+
padding: `${tokens.spacingVerticalXXS} ${tokens.spacingHorizontalXXS}`,
|
|
1372
1437
|
border: `1px solid ${tokens.colorNeutralStroke2}`,
|
|
1438
|
+
borderBottomWidth: 0,
|
|
1373
1439
|
backgroundColor: tokens.colorNeutralBackground1,
|
|
1374
1440
|
},
|
|
1375
1441
|
barTop: {
|
|
1376
1442
|
borderTopWidth: 0,
|
|
1377
1443
|
},
|
|
1378
|
-
barBottom: {
|
|
1379
|
-
borderBottomWidth: 0,
|
|
1380
|
-
},
|
|
1381
1444
|
barLeft: {
|
|
1382
1445
|
marginRight: "auto",
|
|
1383
1446
|
display: "flex",
|
|
@@ -1429,22 +1492,46 @@ const useStyles$b = makeStyles({
|
|
|
1429
1492
|
display: "flex",
|
|
1430
1493
|
flexGrow: 1,
|
|
1431
1494
|
flexDirection: "column",
|
|
1432
|
-
paddingTop: tokens.spacingVerticalS,
|
|
1433
1495
|
overflow: "hidden",
|
|
1434
1496
|
},
|
|
1435
|
-
|
|
1497
|
+
paneHeaderDiv: {
|
|
1498
|
+
display: "flex",
|
|
1499
|
+
flexDirection: "column",
|
|
1500
|
+
justifyContent: "center",
|
|
1501
|
+
backgroundColor: tokens.colorNeutralBackgroundInverted,
|
|
1502
|
+
height: "36px",
|
|
1503
|
+
},
|
|
1504
|
+
paneHeaderText: {
|
|
1436
1505
|
marginLeft: tokens.spacingHorizontalM,
|
|
1506
|
+
color: tokens.colorNeutralForegroundInverted,
|
|
1437
1507
|
},
|
|
1438
|
-
|
|
1508
|
+
paneDivider: {
|
|
1439
1509
|
flex: "0 0 auto",
|
|
1440
1510
|
marginTop: tokens.spacingVerticalM,
|
|
1511
|
+
margin: "0",
|
|
1512
|
+
minHeight: tokens.spacingVerticalM,
|
|
1513
|
+
cursor: "ns-resize",
|
|
1514
|
+
alignItems: "end",
|
|
1515
|
+
},
|
|
1516
|
+
tabToolbar: {
|
|
1517
|
+
padding: 0,
|
|
1441
1518
|
},
|
|
1442
1519
|
tab: {
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1520
|
+
display: "flex",
|
|
1521
|
+
height: "100%",
|
|
1522
|
+
width: "36px",
|
|
1523
|
+
justifyContent: "center",
|
|
1524
|
+
borderTopLeftRadius: tokens.borderRadiusMedium,
|
|
1525
|
+
borderTopRightRadius: tokens.borderRadiusMedium,
|
|
1526
|
+
},
|
|
1527
|
+
unselectedTab: {
|
|
1528
|
+
backgroundColor: "transparent",
|
|
1529
|
+
},
|
|
1530
|
+
tabRadioButton: {
|
|
1531
|
+
backgroundColor: "transparent",
|
|
1532
|
+
},
|
|
1533
|
+
selectedTabIcon: {
|
|
1534
|
+
color: tokens.colorNeutralForeground1,
|
|
1448
1535
|
},
|
|
1449
1536
|
resizer: {
|
|
1450
1537
|
width: "8px",
|
|
@@ -1466,6 +1553,13 @@ const useStyles$b = makeStyles({
|
|
|
1466
1553
|
overflow: "hidden",
|
|
1467
1554
|
},
|
|
1468
1555
|
});
|
|
1556
|
+
const PaneHeader = ({ title }) => {
|
|
1557
|
+
const classes = useStyles$b();
|
|
1558
|
+
if (!title) {
|
|
1559
|
+
return null;
|
|
1560
|
+
}
|
|
1561
|
+
return (jsx("div", { className: classes.paneHeaderDiv, children: jsx(Subtitle2Stronger, { className: classes.paneHeaderText, children: title }) }));
|
|
1562
|
+
};
|
|
1469
1563
|
// 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.
|
|
1470
1564
|
const ToolbarItem = ({ location, alignment, id, component: Component, displayName: displayName, suppressTeachingMoment }) => {
|
|
1471
1565
|
const classes = useStyles$b();
|
|
@@ -1479,16 +1573,21 @@ const Toolbar = ({ location, components }) => {
|
|
|
1479
1573
|
const classes = useStyles$b();
|
|
1480
1574
|
const leftComponents = useMemo(() => components.filter((entry) => entry.horizontalLocation === "left"), [components]);
|
|
1481
1575
|
const rightComponents = useMemo(() => components.filter((entry) => entry.horizontalLocation === "right"), [components]);
|
|
1482
|
-
return (jsx(Fragment, { children: components.length > 0 && (jsxs("div", { className: `${classes.bar} ${location === "top" ? classes.barTop :
|
|
1576
|
+
return (jsx(Fragment, { children: components.length > 0 && (jsxs("div", { className: `${classes.bar} ${location === "top" ? classes.barTop : null}`, children: [jsx("div", { className: classes.barLeft, children: leftComponents.map((entry) => (jsx(ToolbarItem, { location: location, alignment: entry.horizontalLocation, id: entry.key, component: entry.component, displayName: entry.displayName, suppressTeachingMoment: entry.suppressTeachingMoment }, entry.key))) }), jsx("div", { className: classes.barRight, children: rightComponents.map((entry) => (jsx(ToolbarItem, { location: location, alignment: entry.horizontalLocation, id: entry.key, component: entry.component, displayName: entry.displayName, suppressTeachingMoment: entry.suppressTeachingMoment }, entry.key))) })] })) }));
|
|
1483
1577
|
};
|
|
1484
1578
|
// This is a wrapper for a tab in a side pane that simply adds a teaching moment, which is useful for dynamically added items, possibly from extensions.
|
|
1485
|
-
const SidePaneTab = (
|
|
1486
|
-
|
|
1487
|
-
|
|
1579
|
+
const SidePaneTab = (props) => {
|
|
1580
|
+
const { alignment, id, isSelected,
|
|
1581
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
1582
|
+
icon: Icon, title, suppressTeachingMoment, } = props;
|
|
1488
1583
|
const classes = useStyles$b();
|
|
1489
1584
|
const useTeachingMoment = useMemo(() => MakePopoverTeachingMoment(`Pane/${alignment}/${title ?? id}`), [title, id]);
|
|
1490
1585
|
const teachingMoment = useTeachingMoment(suppressTeachingMoment);
|
|
1491
|
-
|
|
1586
|
+
const tabClass = mergeClasses(classes.tab, isSelected ? undefined : classes.unselectedTab);
|
|
1587
|
+
return (jsxs(Fragment, { children: [jsx(TeachingMoment, { ...teachingMoment, shouldDisplay: teachingMoment.shouldDisplay && !suppressTeachingMoment, title: title ?? "Extension", description: `The "${title ?? id}" extension can be accessed here.` }), jsx(Theme, { className: tabClass, invert: isSelected, children: jsx(ToolbarRadioButton, { ref: teachingMoment.targetRef, title: title ?? id, appearance: "transparent", className: classes.tabRadioButton, name: "selectedTab", value: id, icon: {
|
|
1588
|
+
className: isSelected ? classes.selectedTabIcon : undefined,
|
|
1589
|
+
children: jsx(Icon, {}),
|
|
1590
|
+
} }) })] }));
|
|
1492
1591
|
};
|
|
1493
1592
|
// This hook provides a side pane container and the tab list.
|
|
1494
1593
|
// In "compact" mode, the tab list is integrated into the pane itself.
|
|
@@ -1559,15 +1658,18 @@ function usePane(alignment, defaultWidth, minWidth, topPanes, bottomPanes, toolb
|
|
|
1559
1658
|
}, { once: true });
|
|
1560
1659
|
}, [resizing]);
|
|
1561
1660
|
const createPaneTabList = useCallback((paneComponents, toolbarMode, selectedTab, setSelectedTab) => {
|
|
1562
|
-
return (jsx(Fragment, { children: paneComponents.length > 0 && (jsxs("div", { className: `${classes.paneTabListDiv} ${alignment === "left" || toolbarMode === "compact" ? classes.paneTabListDivLeft : classes.paneTabListDivRight}`, children: [paneComponents.length > 1 && (jsx(Fragment, { children: jsx(
|
|
1563
|
-
const tab = paneComponents.find((entry) => entry.key === data.
|
|
1661
|
+
return (jsx(Fragment, { children: paneComponents.length > 0 && (jsxs("div", { className: `${classes.paneTabListDiv} ${alignment === "left" || toolbarMode === "compact" ? classes.paneTabListDivLeft : classes.paneTabListDivRight}`, children: [paneComponents.length > 1 && (jsx(Fragment, { children: jsx(Toolbar$1, { className: classes.tabToolbar, checkedValues: { selectedTab: [selectedTab?.key ?? ""] }, onCheckedValueChange: (event, data) => {
|
|
1662
|
+
const tab = paneComponents.find((entry) => entry.key === data.checkedItems[0]);
|
|
1564
1663
|
setSelectedTab(tab);
|
|
1565
1664
|
setCollapsed(false);
|
|
1566
|
-
}, children: paneComponents.map((entry) =>
|
|
1665
|
+
}, children: paneComponents.map((entry) => {
|
|
1666
|
+
const isSelected = selectedTab?.key === entry.key;
|
|
1667
|
+
return (jsx(SidePaneTab, { alignment: alignment, id: entry.key, title: entry.title, icon: entry.icon, suppressTeachingMoment: entry.suppressTeachingMoment, isSelected: isSelected && !collapsed }, entry.key));
|
|
1668
|
+
}) }) })), toolbarMode === "full" && (jsxs(Fragment, { children: [paneComponents.length > 1 && (jsxs(Fragment, { children: [jsx(Divider, { vertical: true, inset: true, style: { minHeight: 0 } }), " "] })), jsx(Tooltip, { content: collapsed ? "Show Side Pane" : "Hide Side Pane", relationship: "label", children: jsx(Button$1, { className: classes.paneCollapseButton, appearance: "subtle", icon: expandCollapseIcon, onClick: onExpandCollapseClick }) })] }))] })) }));
|
|
1567
1669
|
}, [alignment, collapsed]);
|
|
1568
1670
|
// This memos the TabList to make it easy for the JSX to be inserted at the top of the pane (in "compact" mode) or returned to the caller to be used in the toolbar (in "full" mode).
|
|
1569
|
-
const topPaneTabList = useMemo(() => createPaneTabList(topPanes, toolbarMode, topSelectedTab, setTopSelectedTab), [topPanes, toolbarMode, topSelectedTab]);
|
|
1570
|
-
const bottomPaneTabList = useMemo(() => createPaneTabList(bottomPanes, "compact", bottomSelectedTab, setBottomSelectedTab), [bottomPanes, bottomSelectedTab]);
|
|
1671
|
+
const topPaneTabList = useMemo(() => createPaneTabList(topPanes, toolbarMode, topSelectedTab, setTopSelectedTab), [createPaneTabList, topPanes, toolbarMode, topSelectedTab]);
|
|
1672
|
+
const bottomPaneTabList = useMemo(() => createPaneTabList(bottomPanes, "compact", bottomSelectedTab, setBottomSelectedTab), [createPaneTabList, bottomPanes, bottomSelectedTab]);
|
|
1571
1673
|
// This manages the CSS variable that controls the height of the bottom pane.
|
|
1572
1674
|
const paneHeightAdjustCSSVar = "--pane-height-adjust";
|
|
1573
1675
|
const { elementRef: paneVerticalResizeElementRef, handleRef: paneVerticalResizeHandleRef, setValue: setPaneHeightAdjust, } = useResizeHandle({
|
|
@@ -1589,8 +1691,8 @@ function usePane(alignment, defaultWidth, minWidth, topPanes, bottomPanes, toolb
|
|
|
1589
1691
|
});
|
|
1590
1692
|
// This memoizes the pane itself, which may or may not include the tab list, depending on the toolbar mode.
|
|
1591
1693
|
const pane = useMemo(() => {
|
|
1592
|
-
return (jsx(Fragment, { children: (topPanes.length > 0 || bottomPanes.length > 0) && (jsxs("div", { className: `${classes.pane} ${alignment === "left" ? classes.paneLeft : classes.paneRight}`, children: [jsx(Collapse, { orientation: "horizontal", visible: !collapsed, children: jsxs("div", { className: classes.paneContainer, style: { width: `${width}px` }, children: [toolbarMode === "compact" && (topPanes.length > 1 || topBarItems.length > 0) && (jsx(Fragment, { children: jsxs("div", { className: classes.barDiv, children: [topPaneTabList, jsx(Toolbar, { location: "top", components: topBarItems })] }) })), jsxs("div", { className: classes.paneContent, children: [
|
|
1593
|
-
}, [topPanes, topSelectedTab, bottomPanes, bottomSelectedTab, topBarItems, bottomBarItems, collapsed, width, resizing]);
|
|
1694
|
+
return (jsx(Fragment, { children: (topPanes.length > 0 || bottomPanes.length > 0) && (jsxs("div", { className: `${classes.pane} ${alignment === "left" ? classes.paneLeft : classes.paneRight}`, children: [jsx(Collapse, { orientation: "horizontal", visible: !collapsed, children: jsxs("div", { className: classes.paneContainer, style: { width: `${width}px` }, children: [toolbarMode === "compact" && (topPanes.length > 1 || topBarItems.length > 0) && (jsx(Fragment, { children: jsxs("div", { className: classes.barDiv, children: [topPaneTabList, jsx(Toolbar, { location: "top", components: topBarItems })] }) })), jsxs("div", { className: classes.paneContent, children: [jsx(PaneHeader, { title: topSelectedTab?.title }), topSelectedTab?.content && jsx(topSelectedTab.content, {})] }), topPanes.length > 0 && bottomPanes.length > 0 && jsx(Divider, { ref: paneVerticalResizeHandleRef, className: classes.paneDivider }), bottomPanes.length > 1 && (jsx(Fragment, { children: jsx("div", { className: classes.barDiv, children: bottomPaneTabList }) })), bottomPanes.length > 0 && (jsxs("div", { ref: paneVerticalResizeElementRef, className: classes.paneContent, style: { height: `clamp(200px,calc(45% + var(${paneHeightAdjustCSSVar}, 0px)), 100% - 300px)`, flex: "0 0 auto" }, children: [jsx(PaneHeader, { title: bottomSelectedTab?.title }), bottomSelectedTab?.content && jsx(bottomSelectedTab.content, {})] })), toolbarMode === "compact" && bottomBarItems.length > 0 && (jsx(Fragment, { children: jsx("div", { className: classes.barDiv, children: jsx(Toolbar, { location: "bottom", components: bottomBarItems }) }) }))] }) }), jsx("div", { className: `${classes.resizer} ${alignment === "left" ? classes.resizerLeft : classes.resizerRight}`, style: { pointerEvents: `${collapsed ? "none" : "auto"}` }, onPointerDown: onResizerPointerDown })] })) }));
|
|
1695
|
+
}, [topPanes, topSelectedTab, bottomPanes, bottomSelectedTab, topBarItems, bottomBarItems, topPaneTabList, bottomPaneTabList, collapsed, width, resizing]);
|
|
1594
1696
|
return [topPaneTabList, pane];
|
|
1595
1697
|
}
|
|
1596
1698
|
function MakeShellServiceDefinition({ leftPaneDefaultWidth = 350, leftPaneMinWidth = 350, rightPaneDefaultWidth = 350, rightPaneMinWidth = 350, toolbarMode = "full", sidePaneMode = "both", } = {}) {
|
|
@@ -1873,10 +1975,29 @@ const ToggleCommand = (props) => {
|
|
|
1873
1975
|
// TODO-iv2: Consolidate icon prop passing approach for inspector and shared components
|
|
1874
1976
|
return jsx(ToggleButton, { appearance: "transparent", title: displayName, checkedIcon: Icon, value: isEnabled, onChange: (val) => (command.isEnabled = val) });
|
|
1875
1977
|
};
|
|
1978
|
+
// This "placeholder" command has a blank icon and is a no-op. It is used for aside
|
|
1979
|
+
// alignment when some toggle commands are enabled. See more details on the commands
|
|
1980
|
+
// for setting the aside state.
|
|
1981
|
+
const PlaceHolderCommand = {
|
|
1982
|
+
type: "action",
|
|
1983
|
+
displayName: "",
|
|
1984
|
+
icon: createFluentIcon("Placeholder", "1em", ""),
|
|
1985
|
+
execute: () => {
|
|
1986
|
+
/* No-op */
|
|
1987
|
+
},
|
|
1988
|
+
};
|
|
1989
|
+
function MakeCommandElement(command, isPlaceholder) {
|
|
1990
|
+
if (isPlaceholder) {
|
|
1991
|
+
// Placeholders are not visible and not interacted with, so they are always ActionCommand
|
|
1992
|
+
// components, just to ensure the exact right amount of space is taken up.
|
|
1993
|
+
return jsx(ActionCommand, { command: PlaceHolderCommand }, command.displayName);
|
|
1994
|
+
}
|
|
1995
|
+
return command.type === "action" ? jsx(ActionCommand, { command: command }, command.displayName) : jsx(ToggleCommand, { command: command }, command.displayName);
|
|
1996
|
+
}
|
|
1876
1997
|
const SceneTreeItem = (props) => {
|
|
1877
1998
|
const { isSelected, select } = props;
|
|
1878
1999
|
const classes = useStyles$a();
|
|
1879
|
-
return (jsx(FlatTreeItem, { value: "scene", itemType: "leaf", parentValue: undefined, "aria-level": 1, "aria-setsize": 1, "aria-posinset": 1, onClick: select, children: jsx(TreeItemLayout, { iconBefore: jsx(
|
|
2000
|
+
return (jsx(FlatTreeItem, { value: "scene", itemType: "leaf", parentValue: undefined, "aria-level": 1, "aria-setsize": 1, "aria-posinset": 1, onClick: select, children: jsx(TreeItemLayout, { iconBefore: jsx(GlobeRegular, {}), className: classes.sceneTreeItemLayout, style: isSelected ? { backgroundColor: tokens.colorNeutralBackground1Selected } : undefined, children: jsx(Body1Strong, { wrap: false, truncate: true, children: "Scene" }) }) }, "scene"));
|
|
1880
2001
|
};
|
|
1881
2002
|
const SectionTreeItem = (props) => {
|
|
1882
2003
|
const { section, isFiltering, expandAll, collapseAll } = props;
|
|
@@ -1886,6 +2007,7 @@ const SectionTreeItem = (props) => {
|
|
|
1886
2007
|
};
|
|
1887
2008
|
const EntityTreeItem = (props) => {
|
|
1888
2009
|
const { entityItem, isSelected, select, isFiltering, commandProviders, expandAll, collapseAll } = props;
|
|
2010
|
+
const hasChildren = !!entityItem.children?.length;
|
|
1889
2011
|
const displayInfo = useResource(useCallback(() => {
|
|
1890
2012
|
const displayInfo = entityItem.getDisplayInfo();
|
|
1891
2013
|
if (!displayInfo.dispose) {
|
|
@@ -1898,25 +2020,63 @@ const EntityTreeItem = (props) => {
|
|
|
1898
2020
|
const name = useObservableState(() => displayInfo.name, displayInfo.onChange);
|
|
1899
2021
|
// Get the commands that apply to this entity.
|
|
1900
2022
|
const commands = useResource(useCallback(() => {
|
|
1901
|
-
const commands = commandProviders
|
|
2023
|
+
const commands = [...commandProviders]
|
|
1902
2024
|
.filter((provider) => provider.predicate(entityItem.entity))
|
|
1903
|
-
.map((provider) =>
|
|
2025
|
+
.map((provider) => {
|
|
2026
|
+
return {
|
|
2027
|
+
order: provider.order,
|
|
2028
|
+
command: provider.getCommand(entityItem.entity),
|
|
2029
|
+
};
|
|
2030
|
+
})
|
|
2031
|
+
.sort((a, b) => {
|
|
2032
|
+
// Action commands always come before toggle commands, because toggle commands will remain
|
|
2033
|
+
// visible when they are enabled, even when the pointer is not hovering the item, and we
|
|
2034
|
+
// don't want a bunch of blank space.
|
|
2035
|
+
if (a.command.type !== b.command.type) {
|
|
2036
|
+
return a.command.type === "action" ? -1 : 1;
|
|
2037
|
+
}
|
|
2038
|
+
// Within each group of command types, sort by order (default 0) ascending.
|
|
2039
|
+
return (a.order ?? 0) - (b.order ?? 0);
|
|
2040
|
+
})
|
|
2041
|
+
.map((entry) => entry.command);
|
|
1904
2042
|
return Object.assign(commands, {
|
|
1905
2043
|
dispose: () => commands.forEach((command) => command.dispose?.()),
|
|
1906
2044
|
});
|
|
1907
2045
|
}, [entityItem.entity, commandProviders]));
|
|
1908
|
-
|
|
1909
|
-
|
|
2046
|
+
// TreeItemLayout actions (totally unrelated to "Action" type commands) are only visible when the item is focused or has pointer hover.
|
|
2047
|
+
const actions = useMemo(() => {
|
|
2048
|
+
const defaultCommands = [];
|
|
2049
|
+
if (hasChildren) {
|
|
2050
|
+
defaultCommands.push({
|
|
2051
|
+
type: "action",
|
|
2052
|
+
displayName: "Expand All",
|
|
2053
|
+
icon: () => jsx(ArrowExpandAllRegular, {}),
|
|
2054
|
+
execute: () => expandAll(),
|
|
2055
|
+
});
|
|
2056
|
+
}
|
|
2057
|
+
return [...defaultCommands, ...commands].map((command) => MakeCommandElement(command, false));
|
|
2058
|
+
}, [commands, hasChildren, expandAll]);
|
|
2059
|
+
// TreeItemLayout asides are always visible.
|
|
2060
|
+
const [aside, setAside] = useState([]);
|
|
2061
|
+
// This useEffect keeps the aside up-to-date. What should always show is any enabled toggle command, along with
|
|
2062
|
+
// placeholders to the right to keep the position of the actions consistent.
|
|
1910
2063
|
useEffect(() => {
|
|
1911
|
-
const
|
|
1912
|
-
|
|
1913
|
-
|
|
2064
|
+
const updateAside = () => {
|
|
2065
|
+
let isAnyCommandEnabled = false;
|
|
2066
|
+
const aside = [];
|
|
2067
|
+
for (const command of commands) {
|
|
2068
|
+
isAnyCommandEnabled || (isAnyCommandEnabled = command.type === "toggle" && command.isEnabled);
|
|
2069
|
+
if (isAnyCommandEnabled) {
|
|
2070
|
+
aside.push(MakeCommandElement(command, command.type !== "toggle" || !command.isEnabled));
|
|
2071
|
+
}
|
|
2072
|
+
}
|
|
2073
|
+
setAside(aside);
|
|
1914
2074
|
};
|
|
1915
|
-
|
|
1916
|
-
const observers =
|
|
2075
|
+
updateAside();
|
|
2076
|
+
const observers = commands
|
|
1917
2077
|
.map((command) => command.onChange)
|
|
1918
2078
|
.filter((onChange) => !!onChange)
|
|
1919
|
-
.map((onChange) => onChange.add(
|
|
2079
|
+
.map((onChange) => onChange.add(updateAside));
|
|
1920
2080
|
return () => {
|
|
1921
2081
|
for (const observer of observers) {
|
|
1922
2082
|
observer.remove();
|
|
@@ -1925,15 +2085,14 @@ const EntityTreeItem = (props) => {
|
|
|
1925
2085
|
}, [commands]);
|
|
1926
2086
|
return (jsxs(Menu, { openOnContext: true, children: [jsx(MenuTrigger, { disableButtonEnhancement: true, children: jsx(FlatTreeItem, { value: entityItem.entity.uniqueId,
|
|
1927
2087
|
// Disable manual expand/collapse when a filter is active.
|
|
1928
|
-
itemType: !isFiltering &&
|
|
1929
|
-
// Actions are only visible when the item is focused or has pointer hover.
|
|
1930
|
-
actions: commands.map((command) => command.type === "action" ? (jsx(ActionCommand, { command: command }, command.displayName)) : (jsx(ToggleCommand, { command: command }, command.displayName))),
|
|
1931
|
-
// Asides are always visible.
|
|
1932
|
-
aside: {
|
|
2088
|
+
itemType: !isFiltering && hasChildren ? "branch" : "leaf", parentValue: entityItem.parent.type === "section" ? entityItem.parent.sectionName : entityItem.entity.uniqueId, "aria-level": entityItem.depth, "aria-setsize": 1, "aria-posinset": 1, onClick: select, children: jsx(TreeItemLayout, { iconBefore: entityItem.icon ? jsx(entityItem.icon, { entity: entityItem.entity }) : null, style: isSelected ? { backgroundColor: tokens.colorNeutralBackground1Selected } : undefined, actions: actions, aside: {
|
|
1933
2089
|
// Match the gap and padding of the actions.
|
|
1934
|
-
style: { gap: 0, paddingRight: tokens.spacingHorizontalS },
|
|
1935
|
-
children:
|
|
1936
|
-
},
|
|
2090
|
+
style: { gap: 0, paddingLeft: tokens.spacingHorizontalS, paddingRight: tokens.spacingHorizontalS },
|
|
2091
|
+
children: aside,
|
|
2092
|
+
}, main: {
|
|
2093
|
+
// Prevent the "main" content (the Body1 below) from growing too large and pushing the actions/aside out of view.
|
|
2094
|
+
style: { flex: "1 1 0", overflow: "hidden", textOverflow: "ellipsis" },
|
|
2095
|
+
}, children: jsx(Body1, { wrap: false, truncate: true, children: name }) }) }, entityItem.entity.uniqueId) }), jsx(MenuPopover, { hidden: !hasChildren, children: jsxs(MenuList, { children: [jsx(MenuItem, { onClick: expandAll, children: jsx(Body1, { children: "Expand All" }) }), jsx(MenuItem, { onClick: collapseAll, children: jsx(Body1, { children: "Collapse All" }) })] }) })] }));
|
|
1937
2096
|
};
|
|
1938
2097
|
const SceneExplorer = (props) => {
|
|
1939
2098
|
const classes = useStyles$a();
|
|
@@ -2859,19 +3018,19 @@ const DefaultInspectorExtensionFeed = new BuiltInsExtensionFeed("Inspector", [
|
|
|
2859
3018
|
name: "Export Tools",
|
|
2860
3019
|
description: "Adds new features to enable exporting Babylon assets such as .gltf, .glb, .babylon, and more.",
|
|
2861
3020
|
keywords: ["export", "gltf", "glb", "babylon", "exporter", "tools"],
|
|
2862
|
-
getExtensionModuleAsync: async () => await import('./exportService-
|
|
3021
|
+
getExtensionModuleAsync: async () => await import('./exportService-Cu9CXW_A.js'),
|
|
2863
3022
|
},
|
|
2864
3023
|
{
|
|
2865
3024
|
name: "Capture Tools",
|
|
2866
3025
|
description: "Adds new features to enable capturing screenshots, GIFs, videos, and more.",
|
|
2867
3026
|
keywords: ["capture", "screenshot", "gif", "video", "tools"],
|
|
2868
|
-
getExtensionModuleAsync: async () => await import('./captureService-
|
|
3027
|
+
getExtensionModuleAsync: async () => await import('./captureService-CuhjVz1y.js'),
|
|
2869
3028
|
},
|
|
2870
3029
|
{
|
|
2871
3030
|
name: "Import Tools",
|
|
2872
3031
|
description: "Adds new features related to importing Babylon assets.",
|
|
2873
3032
|
keywords: ["import", "tools"],
|
|
2874
|
-
getExtensionModuleAsync: async () => await import('./importService-
|
|
3033
|
+
getExtensionModuleAsync: async () => await import('./importService-BETG4FuQ.js'),
|
|
2875
3034
|
},
|
|
2876
3035
|
]);
|
|
2877
3036
|
|
|
@@ -3147,27 +3306,6 @@ class ExtensionManager {
|
|
|
3147
3306
|
}
|
|
3148
3307
|
}
|
|
3149
3308
|
|
|
3150
|
-
const ThemeModeStorageKey = `Babylon/Settings/ThemeMode`;
|
|
3151
|
-
/**
|
|
3152
|
-
* Custom hook to manage the theme mode (light/dark/auto).
|
|
3153
|
-
* @param modeOverride If specified, any previously stored theme mode will be replaced with this mode.
|
|
3154
|
-
* @returns An object containing the theme mode state and helper functions.
|
|
3155
|
-
*/
|
|
3156
|
-
function useThemeMode(modeOverride) {
|
|
3157
|
-
const { isDarkMode, ternaryDarkMode, setTernaryDarkMode } = useTernaryDarkMode({
|
|
3158
|
-
defaultValue: modeOverride,
|
|
3159
|
-
initializeWithValue: !modeOverride,
|
|
3160
|
-
localStorageKey: ThemeModeStorageKey,
|
|
3161
|
-
});
|
|
3162
|
-
// If a modeOverride is provided, replace any previously stored mode.
|
|
3163
|
-
// Also make sure there is a stored value initially, even before changing the theme.
|
|
3164
|
-
// This way, other usages of this hook will get the correct initial value.
|
|
3165
|
-
if (modeOverride || !localStorage.getItem(ThemeModeStorageKey)) {
|
|
3166
|
-
localStorage.setItem(ThemeModeStorageKey, JSON.stringify(ternaryDarkMode));
|
|
3167
|
-
}
|
|
3168
|
-
return { isDarkMode, themeMode: ternaryDarkMode, setThemeMode: setTernaryDarkMode };
|
|
3169
|
-
}
|
|
3170
|
-
|
|
3171
3309
|
// This sorts a set of service definitions based on their dependencies (e.g. a topological sort).
|
|
3172
3310
|
function SortServiceDefinitions(serviceDefinitions) {
|
|
3173
3311
|
const sortedServiceDefinitions = [];
|
|
@@ -3458,7 +3596,7 @@ const ThemeSelectorServiceDefinition = {
|
|
|
3458
3596
|
const toggleTheme = useCallback(() => {
|
|
3459
3597
|
setThemeMode(isDarkMode ? "light" : "dark");
|
|
3460
3598
|
}, [isDarkMode]);
|
|
3461
|
-
return (jsxs(Menu, { positioning: "below-end", checkedValues: { theme: [themeMode] }, onCheckedValueChange: onSelectedThemeChange, children: [jsx(MenuTrigger, { disableButtonEnhancement: true, children: (triggerProps) => (jsx(Tooltip, { content: "Select Theme", relationship: "label", children: jsx(SplitButton, { className: classes.themeButton, menuButton: triggerProps, primaryActionButton: { onClick: toggleTheme }, size: "small", appearance: "
|
|
3599
|
+
return (jsxs(Menu, { positioning: "below-end", checkedValues: { theme: [themeMode] }, onCheckedValueChange: onSelectedThemeChange, children: [jsx(MenuTrigger, { disableButtonEnhancement: true, children: (triggerProps) => (jsx(Tooltip, { content: "Select Theme", relationship: "label", children: jsx(SplitButton, { className: classes.themeButton, menuButton: triggerProps, primaryActionButton: { onClick: toggleTheme }, size: "small", appearance: "transparent", shape: "circular", icon: isDarkMode ? jsx(WeatherSunnyRegular, {}) : jsx(WeatherMoonRegular, {}) }) })) }), jsx(MenuPopover, { className: classes.themeMenuPopover, children: jsxs(MenuList, { children: [jsx(MenuItemRadio, { name: "theme", value: "system", children: "System" }), jsx(MenuItemRadio, { name: "theme", value: "light", children: "Light" }), jsx(MenuItemRadio, { name: "theme", value: "dark", children: "Dark" })] }) })] }));
|
|
3462
3600
|
},
|
|
3463
3601
|
});
|
|
3464
3602
|
return {
|
|
@@ -3467,34 +3605,6 @@ const ThemeSelectorServiceDefinition = {
|
|
|
3467
3605
|
},
|
|
3468
3606
|
};
|
|
3469
3607
|
|
|
3470
|
-
/* eslint-disable @typescript-eslint/naming-convention */
|
|
3471
|
-
// Generated from https://react.fluentui.dev/?path=/docs/theme-theme-designer--docs
|
|
3472
|
-
// Key color: #3A94FC
|
|
3473
|
-
const babylonRamp = {
|
|
3474
|
-
10: "#020305",
|
|
3475
|
-
20: "#121721",
|
|
3476
|
-
30: "#1A263A",
|
|
3477
|
-
40: "#1F314F",
|
|
3478
|
-
50: "#243E64",
|
|
3479
|
-
60: "#294B7B",
|
|
3480
|
-
70: "#2D5892",
|
|
3481
|
-
80: "#3166AA",
|
|
3482
|
-
90: "#3473C3",
|
|
3483
|
-
100: "#3782DC",
|
|
3484
|
-
110: "#3990F6",
|
|
3485
|
-
120: "#5A9EFD",
|
|
3486
|
-
130: "#7BACFE",
|
|
3487
|
-
140: "#96BAFF",
|
|
3488
|
-
150: "#AFC9FF",
|
|
3489
|
-
160: "#C6D8FF",
|
|
3490
|
-
};
|
|
3491
|
-
const LightTheme = {
|
|
3492
|
-
...createLightTheme(babylonRamp),
|
|
3493
|
-
};
|
|
3494
|
-
const DarkTheme = {
|
|
3495
|
-
...createDarkTheme(babylonRamp),
|
|
3496
|
-
};
|
|
3497
|
-
|
|
3498
3608
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
3499
3609
|
const useStyles$6 = makeStyles({
|
|
3500
3610
|
app: {
|
|
@@ -3528,10 +3638,12 @@ const useStyles$6 = makeStyles({
|
|
|
3528
3638
|
*/
|
|
3529
3639
|
function MakeModularTool(options) {
|
|
3530
3640
|
const { containerElement, serviceDefinitions, themeMode, showThemeSelector = true, extensionFeeds = [] } = options;
|
|
3641
|
+
if (themeMode) {
|
|
3642
|
+
SetThemeMode(themeMode);
|
|
3643
|
+
}
|
|
3531
3644
|
const modularToolRootComponent = () => {
|
|
3532
3645
|
const classes = useStyles$6();
|
|
3533
3646
|
const [extensionManagerContext, setExtensionManagerContext] = useState();
|
|
3534
|
-
const { isDarkMode } = useThemeMode(themeMode);
|
|
3535
3647
|
const [requiredExtensions, setRequiredExtensions] = useState();
|
|
3536
3648
|
const [requiredExtensionsDeferred, setRequiredExtensionsDeferred] = useState();
|
|
3537
3649
|
const [extensionInstallError, setExtensionInstallError] = useState();
|
|
@@ -3628,7 +3740,7 @@ function MakeModularTool(options) {
|
|
|
3628
3740
|
// Show a spinner until a main view has been set.
|
|
3629
3741
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
3630
3742
|
const Content = rootComponent ?? (() => jsx(Spinner, { className: classes.spinner }));
|
|
3631
|
-
return (jsx(ExtensionManagerContext.Provider, { value: extensionManagerContext, children: jsx(
|
|
3743
|
+
return (jsx(ExtensionManagerContext.Provider, { value: extensionManagerContext, children: jsx(Theme, { className: classes.app, children: jsxs(Fragment, { 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, {}) })] }) }) }));
|
|
3632
3744
|
};
|
|
3633
3745
|
// Set the container element to be a flex container so that the tool can be displayed properly.
|
|
3634
3746
|
const originalContainerElementDisplay = containerElement.style.display;
|
|
@@ -3729,6 +3841,10 @@ const GizmoServiceDefinition = {
|
|
|
3729
3841
|
},
|
|
3730
3842
|
};
|
|
3731
3843
|
|
|
3844
|
+
const MeshIcon = createFluentIcon("Mesh", "16", '<path d="M14.03,3.54l-5.11-2.07c-.61-.25-1.27-.25-1.88,0L1.93,3.54c-.57.23-.94.78-.94,1.39v6.15c0,.61.37,1.16.94,1.39l5.11,2.07c.3.12.62.18.94.18s.64-.06.94-.18l5.12-2.07c.57-.23.94-.78.94-1.39v-6.15c0-.61-.37-1.16-.94-1.39ZM13.97,7.71l-2.11.86v-2.71l2.11-.86v2.71ZM1.99,5l2.11.86v2.71l-2.11-.86v-2.71ZM11.35,4.98l-2.04-.83,1.78-.72,2.04.83-1.78.72ZM10.02,5.52l-2.04.83-2.04-.83,2.04-.83,2.04.83ZM4.6,4.98l-1.78-.72,2.04-.83,1.78.72-2.04.83ZM5.1,6.26l2.38.96v2.71l-2.38-.96v-2.71ZM8.48,7.22l2.38-.96v2.71l-2.38.96v-2.71ZM7.41,2.39c.18-.07.37-.11.56-.11s.38.04.56.11l1.22.49-1.78.72-1.79-.72,1.22-.49ZM1.99,11.07v-2.29l2.11.86v2.62l-1.8-.73c-.19-.08-.31-.26-.31-.46ZM5.1,12.67v-2.62l2.38.96v2.61s-.04,0-.06-.01l-2.31-.94ZM8.54,13.61s-.04,0-.06.01v-2.61l2.38-.96v2.62l-2.31.94ZM13.66,11.54l-1.8.73v-2.62l2.11-.86v2.29c0,.2-.12.39-.31.46Z"/>');
|
|
3845
|
+
const TranslateIcon = createFluentIcon("Translate", "24", '<path d="M20.16,12.98l-2.75-2.75c-.29-.29-.77-.29-1.06,0-.29.29-.29.77,0,1.06l1.47,1.47h-6.69v-6.69l1.47,1.47c.29.29.77.29,1.06,0,.29-.29.29-.77,0-1.06l-2.75-2.75c-.14-.14-.33-.22-.53-.22s-.39.08-.53.22l-2.75,2.75c-.29.29-.29.77,0,1.06.29.29.77.29,1.06,0l1.47-1.47v7.13l-3.52,3.52v-2.08c0-.41-.34-.75-.75-.75s-.75.34-.75.75v3.89c0,.2.08.39.22.53.14.14.33.22.53.22h3.89c.41,0,.75-.34.75-.75s-.34-.75-.75-.75h-2.08s3.52-3.52,3.52-3.52h7.13l-1.47,1.47c-.29.29-.29.77,0,1.06s.77.29,1.06,0l2.75-2.75c.14-.14.22-.33.22-.53s-.08-.39-.22-.53Z" />');
|
|
3846
|
+
const MaterialIcon = createFluentIcon("Material", "16", '<path d="M14.74,6.3c-.09-.36-.38-.64-.75-.72-.04-.09-.08-.18-.12-.27.1-.15.16-.32.16-.51,0-.18-.05-.34-.13-.48-1.23-1.97-3.41-3.28-5.9-3.28C4.16,1.04,1.04,4.16,1.04,7.99c0,.39.23.72.57.88.02.12.03.25.06.37-.18.18-.3.42-.3.7,0,.11.02.21.06.31.94,2.74,3.53,4.71,6.58,4.71,3.84,0,6.96-3.12,6.96-6.96,0-.59-.08-1.16-.22-1.7ZM2.07,8.58c-.02-.19-.03-.39-.03-.58,0-3.29,2.67-5.96,5.96-5.96,2.23,0,4.17,1.23,5.2,3.05.05.18-.07.45-.3.75-.57-.73-1.45-1.21-2.45-1.21-1.72,0-3.12,1.4-3.12,3.11,0,.33.07.65.16.95-3.05.82-5.17.52-5.42-.11ZM12.56,7.75c0,1.17-.95,2.11-2.11,2.11s-2.12-.95-2.12-2.11.95-2.11,2.12-2.11,2.11.95,2.11,2.11ZM8,13.96c-2.6,0-4.81-1.68-5.62-4.01.5.16,1.11.24,1.79.24,1.15,0,2.49-.22,3.79-.59.57.76,1.47,1.26,2.49,1.26,1.72,0,3.11-1.4,3.11-3.11,0-.34-.07-.65-.17-.96.13-.13.24-.26.34-.39.14.51.22,1.04.22,1.6,0,3.29-2.67,5.96-5.96,5.96Z"/>');
|
|
3847
|
+
|
|
3732
3848
|
const useStyles$5 = makeStyles({
|
|
3733
3849
|
coordinatesModeButton: {
|
|
3734
3850
|
margin: `0 ${tokens.spacingVerticalXS}`,
|
|
@@ -3831,9 +3947,9 @@ const GizmoToolbar = (props) => {
|
|
|
3831
3947
|
const toggleCoordinatesMode = useCallback(() => {
|
|
3832
3948
|
gizmoManager.coordinatesMode = coordinatesMode === 1 /* GizmoCoordinatesMode.Local */ ? 0 /* GizmoCoordinatesMode.World */ : 1 /* GizmoCoordinatesMode.Local */;
|
|
3833
3949
|
}, [gizmoManager, coordinatesMode]);
|
|
3834
|
-
return (jsxs(Fragment, { children: [jsx(ToggleButton, { title: "Translate", checkedIcon:
|
|
3950
|
+
return (jsxs(Fragment, { children: [jsx(ToggleButton, { title: "Translate", checkedIcon: TranslateIcon, value: gizmoMode === "translate", onChange: () => updateGizmoMode("translate") }), jsx(ToggleButton, { title: "Rotate", checkedIcon: ArrowRotateClockwiseRegular, value: gizmoMode === "rotate", onChange: () => updateGizmoMode("rotate") }), jsx(ToggleButton, { title: "Scale", checkedIcon: ArrowExpandRegular, value: gizmoMode === "scale", onChange: () => updateGizmoMode("scale") }), jsx(ToggleButton, { title: "Bounding Box", checkedIcon: SelectObjectRegular, value: gizmoMode === "boundingBox", onChange: () => updateGizmoMode("boundingBox") }), jsx(Collapse, { visible: !!gizmoMode, orientation: "horizontal", children: jsxs(Menu, { positioning: "below-end", checkedValues: { coordinatesMode: [coordinatesMode.toString()] }, onCheckedValueChange: onCoordinatesModeChange, children: [jsx(MenuTrigger, { disableButtonEnhancement: true, children: (triggerProps) => (jsx(Tooltip, { content: "Coordinates Mode", relationship: "label", children: jsx(SplitButton, { className: classes.coordinatesModeButton, menuButton: triggerProps, primaryActionButton: {
|
|
3835
3951
|
onClick: toggleCoordinatesMode,
|
|
3836
|
-
}, size: "small", appearance: "
|
|
3952
|
+
}, size: "small", appearance: "transparent", shape: "rounded", icon: coordinatesMode === 1 /* GizmoCoordinatesMode.Local */ ? jsx(CubeRegular, {}) : jsx(GlobeRegular, {}) }) })) }), jsx(MenuPopover, { className: classes.coordinatesModeMenu, children: jsxs(MenuList, { children: [jsx(MenuItemRadio, { name: "coordinatesMode", value: 1 /* GizmoCoordinatesMode.Local */.toString(), children: "Local" }), jsx(MenuItemRadio, { name: "coordinatesMode", value: 0 /* GizmoCoordinatesMode.World */.toString(), children: "World" })] }) })] }) })] }));
|
|
3837
3953
|
};
|
|
3838
3954
|
|
|
3839
3955
|
const GizmoToolbarServiceDefinition = {
|
|
@@ -3903,7 +4019,7 @@ const TextInput = (props) => {
|
|
|
3903
4019
|
};
|
|
3904
4020
|
const mergedClassName = mergeClasses(classes.input, !validateValue(value) ? classes.invalid : "", props.className);
|
|
3905
4021
|
const id = useId("input-button");
|
|
3906
|
-
return (jsxs("div", { className: classes.container, children: [props.infoLabel && jsx(InfoLabel, { ...props.infoLabel, htmlFor: id }), jsx(Input, { ...props, id: id, size: "medium", value: value, onChange: handleChange, onKeyUp: handleKeyUp, onKeyDown: HandleKeyDown, onBlur: HandleOnBlur, className: mergedClassName })] }));
|
|
4022
|
+
return (jsxs("div", { className: classes.container, children: [props.infoLabel && jsx(InfoLabel, { ...props.infoLabel, htmlFor: id }), jsx(Input, { ...props, input: { className: classes.inputSlot }, id: id, size: "medium", value: value, onChange: handleChange, onKeyUp: handleKeyUp, onKeyDown: HandleKeyDown, onBlur: HandleOnBlur, className: mergedClassName })] }));
|
|
3907
4023
|
};
|
|
3908
4024
|
|
|
3909
4025
|
const SpinButton = (props) => {
|
|
@@ -3951,7 +4067,7 @@ const SpinButton = (props) => {
|
|
|
3951
4067
|
};
|
|
3952
4068
|
const id = useId("spin-button");
|
|
3953
4069
|
const mergedClassName = mergeClasses(classes.input, !validateValue(value) ? classes.invalid : "", props.className);
|
|
3954
|
-
return (jsxs("div", { className: classes.container, children: [props.infoLabel && jsx(InfoLabel, { ...props.infoLabel, htmlFor: id }), jsx(SpinButton$1, { ...props, step: step, id: id, size: "medium", precision: CalculatePrecision(step ?? 1.01), displayValue: props.unit ? `${PrecisionRound(value, CalculatePrecision(step ?? 1.01))} ${props.unit}` : undefined, value: value, onChange: handleChange, onKeyUp: handleKeyUp, onKeyDown: HandleKeyDown, onBlur: HandleOnBlur, className: mergedClassName })] }));
|
|
4070
|
+
return (jsxs("div", { className: classes.container, children: [props.infoLabel && jsx(InfoLabel, { ...props.infoLabel, htmlFor: id }), jsx(SpinButton$1, { ...props, input: { className: classes.inputSlot }, step: step, id: id, size: "medium", precision: CalculatePrecision(step ?? 1.01), displayValue: props.unit ? `${PrecisionRound(value, CalculatePrecision(step ?? 1.01))} ${props.unit}` : undefined, value: value, onChange: handleChange, onKeyUp: handleKeyUp, onKeyDown: HandleKeyDown, onBlur: HandleOnBlur, className: mergedClassName })] }));
|
|
3955
4071
|
};
|
|
3956
4072
|
/**
|
|
3957
4073
|
* Fluent's CalculatePrecision function
|
|
@@ -4326,6 +4442,7 @@ const useDropdownStyles = makeStyles({
|
|
|
4326
4442
|
justifyContent: "center", // align items vertically
|
|
4327
4443
|
gap: "4px",
|
|
4328
4444
|
},
|
|
4445
|
+
button: { textAlign: "end" },
|
|
4329
4446
|
});
|
|
4330
4447
|
/**
|
|
4331
4448
|
* Renders a fluent UI dropdown component for the options passed in, and an additional 'Not Defined' option if null is set to true
|
|
@@ -4343,7 +4460,7 @@ const Dropdown = (props) => {
|
|
|
4343
4460
|
}, [props.value]);
|
|
4344
4461
|
const id = useId("dropdown");
|
|
4345
4462
|
const mergedClassName = mergeClasses(classes.dropdown, props.className);
|
|
4346
|
-
return (jsxs("div", { className: classes.container, children: [props.infoLabel && jsx(InfoLabel, { ...props.infoLabel, htmlFor: id }), jsx(Dropdown$1, { id: id, disabled: props.disabled, size: "medium", className: mergedClassName, onOptionSelect: (evt, data) => {
|
|
4463
|
+
return (jsxs("div", { className: classes.container, children: [props.infoLabel && jsx(InfoLabel, { ...props.infoLabel, htmlFor: id }), jsx(Dropdown$1, { id: id, disabled: props.disabled, size: "medium", className: mergedClassName, button: { className: classes.button }, onOptionSelect: (evt, data) => {
|
|
4347
4464
|
const value = typeof props.value === "number" ? Number(data.optionValue) : data.optionValue;
|
|
4348
4465
|
if (value !== undefined) {
|
|
4349
4466
|
setDefaultVal(value);
|
|
@@ -5577,6 +5694,11 @@ function SaveMetadata(entity, metadata) {
|
|
|
5577
5694
|
}
|
|
5578
5695
|
}
|
|
5579
5696
|
const useStyles$4 = makeStyles({
|
|
5697
|
+
mainDiv: {
|
|
5698
|
+
display: "flex",
|
|
5699
|
+
flexDirection: "column",
|
|
5700
|
+
gap: tokens.spacingVerticalXS,
|
|
5701
|
+
},
|
|
5580
5702
|
buttonDiv: {
|
|
5581
5703
|
display: "grid",
|
|
5582
5704
|
gridAutoFlow: "column",
|
|
@@ -5601,14 +5723,14 @@ const MetadataProperties = (props) => {
|
|
|
5601
5723
|
const [editedMetadata, setEditedMetadata] = useState(stringifiedMetadata);
|
|
5602
5724
|
const isEditedMetadataJSON = useMemo(() => IsParsable(editedMetadata), [editedMetadata]);
|
|
5603
5725
|
const unformattedEditedMetadata = useMemo(() => Restringify(editedMetadata, false), [editedMetadata]);
|
|
5604
|
-
return (jsxs(Fragment, { children: [jsx(TextPropertyLine, { label: "Property Type", value: metadataType }), jsx(Collapse, { visible: canPreventObjectCorruption, children: jsx(SwitchPropertyLine, { label: "Prevent Object Corruption", value: isReadonly, onChange: setPreventObjectCorruption }) }), jsx(Textarea, { disabled: isReadonly, value: editedMetadata, onChange: setEditedMetadata }), jsx(ButtonLine, { label: "Populate glTF extras", disabled: !IsParsable(editedMetadata) || HasGltfExtras(editedMetadata), onClick: () => {
|
|
5605
|
-
|
|
5606
|
-
|
|
5607
|
-
|
|
5608
|
-
|
|
5609
|
-
|
|
5610
|
-
|
|
5611
|
-
|
|
5726
|
+
return (jsxs(Fragment, { children: [jsx(TextPropertyLine, { label: "Property Type", value: metadataType }), jsx(Collapse, { visible: canPreventObjectCorruption, children: jsx(SwitchPropertyLine, { label: "Prevent Object Corruption", value: isReadonly, onChange: setPreventObjectCorruption }) }), jsxs("div", { className: classes.mainDiv, children: [jsx(Textarea, { disabled: isReadonly, value: editedMetadata, onChange: setEditedMetadata }), jsx(ButtonLine, { label: "Populate glTF extras", disabled: !!editedMetadata && (!IsParsable(editedMetadata) || HasGltfExtras(editedMetadata)), onClick: () => {
|
|
5727
|
+
const isFormatted = Restringify(editedMetadata, true) === editedMetadata;
|
|
5728
|
+
let withGLTFExtras = PopulateGLTFExtras(editedMetadata);
|
|
5729
|
+
if (isFormatted) {
|
|
5730
|
+
withGLTFExtras = Restringify(withGLTFExtras, true);
|
|
5731
|
+
}
|
|
5732
|
+
setEditedMetadata(withGLTFExtras);
|
|
5733
|
+
} }), jsx(LineContainer, { children: jsxs("div", { className: classes.buttonDiv, children: [jsx(Button$1, { icon: jsx(SaveRegular, {}), disabled: stringifiedMetadata === unformattedEditedMetadata, onClick: () => SaveMetadata(entity, editedMetadata), children: jsx(Body1, { children: "Save" }) }), jsx(Tooltip, { content: "Undo Changes", relationship: "label", children: jsx(Button$1, { icon: jsx(ArrowUndoRegular, {}), disabled: stringifiedMetadata === unformattedEditedMetadata, onClick: () => setEditedMetadata(stringifiedMetadata) }) }), jsx(Tooltip, { content: "Format (Pretty Print)", relationship: "label", children: jsx(Button$1, { icon: jsx(BracesRegular, {}), disabled: !isEditedMetadataJSON, onClick: () => setEditedMetadata(Restringify(editedMetadata, true)) }) }), jsx(Tooltip, { content: "Clear Formatting (Undo Pretty Print)", relationship: "label", children: jsx(Button$1, { icon: jsx(BracesDismiss16Regular, {}), disabled: !isEditedMetadataJSON, onClick: () => setEditedMetadata(Restringify(editedMetadata, false)) }) })] }) })] })] }));
|
|
5612
5734
|
};
|
|
5613
5735
|
|
|
5614
5736
|
function IsMetadataContainer(entity) {
|
|
@@ -7476,6 +7598,7 @@ const AnimationGroupExplorerServiceDefinition = {
|
|
|
7476
7598
|
});
|
|
7477
7599
|
const animationPlayPauseCommandRegistration = sceneExplorerService.addCommand({
|
|
7478
7600
|
predicate: (entity) => entity instanceof AnimationGroup,
|
|
7601
|
+
order: 900 /* DefaultCommandsOrder.AnimationGroupPlay */,
|
|
7479
7602
|
getCommand: (animationGroup) => {
|
|
7480
7603
|
const onChangeObservable = new Observable();
|
|
7481
7604
|
const playObserver = animationGroup.onAnimationGroupPlayObservable.add(() => onChangeObservable.notifyObservers());
|
|
@@ -7638,6 +7761,7 @@ const FrameGraphExplorerServiceDefinition = {
|
|
|
7638
7761
|
});
|
|
7639
7762
|
const activeFrameGraphCommandRegistration = sceneExplorerService.addCommand({
|
|
7640
7763
|
predicate: (entity) => entity instanceof FrameGraph,
|
|
7764
|
+
order: 900 /* DefaultCommandsOrder.FrameGraphPlay */,
|
|
7641
7765
|
getCommand: (frameGraph) => {
|
|
7642
7766
|
const onChangeObservable = new Observable();
|
|
7643
7767
|
const frameGraphHook = InterceptProperty(scene, "frameGraph", {
|
|
@@ -7748,7 +7872,7 @@ const MaterialExplorerServiceDefinition = {
|
|
|
7748
7872
|
},
|
|
7749
7873
|
};
|
|
7750
7874
|
},
|
|
7751
|
-
entityIcon: () => jsx(
|
|
7875
|
+
entityIcon: () => jsx(MaterialIcon, {}),
|
|
7752
7876
|
getEntityAddedObservables: () => [scene.onNewMaterialAddedObservable],
|
|
7753
7877
|
getEntityRemovedObservables: () => [scene.onMaterialRemovedObservable],
|
|
7754
7878
|
});
|
|
@@ -7796,7 +7920,7 @@ const NodeExplorerServiceDefinition = {
|
|
|
7796
7920
|
},
|
|
7797
7921
|
};
|
|
7798
7922
|
},
|
|
7799
|
-
entityIcon: ({ entity: node }) => node instanceof AbstractMesh ? (jsx(
|
|
7923
|
+
entityIcon: ({ entity: node }) => node instanceof AbstractMesh ? (jsx(MeshIcon, {})) : node instanceof TransformNode ? (jsx(MyLocationRegular, {})) : node instanceof Camera ? (jsx(CameraRegular, {})) : node instanceof Light ? (jsx(LightbulbRegular, {})) : (jsx(Fragment, {})),
|
|
7800
7924
|
getEntityAddedObservables: () => [
|
|
7801
7925
|
scene.onNewMeshAddedObservable,
|
|
7802
7926
|
scene.onNewTransformNodeAddedObservable,
|
|
@@ -7811,8 +7935,37 @@ const NodeExplorerServiceDefinition = {
|
|
|
7811
7935
|
],
|
|
7812
7936
|
getEntityMovedObservables: () => [nodeMovedObservable],
|
|
7813
7937
|
});
|
|
7938
|
+
const abstractMeshBoundingBoxCommandRegistration = sceneExplorerService.addCommand({
|
|
7939
|
+
predicate: (entity) => entity instanceof AbstractMesh && entity.getTotalVertices() > 0,
|
|
7940
|
+
order: 1000 /* DefaultCommandsOrder.MeshBoundingBox */,
|
|
7941
|
+
getCommand: (mesh) => {
|
|
7942
|
+
const onChangeObservable = new Observable();
|
|
7943
|
+
const showBoundingBoxHook = InterceptProperty(mesh, "showBoundingBox", {
|
|
7944
|
+
afterSet: () => onChangeObservable.notifyObservers(),
|
|
7945
|
+
});
|
|
7946
|
+
return {
|
|
7947
|
+
type: "toggle",
|
|
7948
|
+
get displayName() {
|
|
7949
|
+
return `${mesh.showBoundingBox ? "Hide" : "Show"} Bounding Box`;
|
|
7950
|
+
},
|
|
7951
|
+
icon: () => (mesh.showBoundingBox ? jsx(BorderOutsideRegular, {}) : jsx(BorderNoneRegular, {})),
|
|
7952
|
+
get isEnabled() {
|
|
7953
|
+
return mesh.showBoundingBox;
|
|
7954
|
+
},
|
|
7955
|
+
set isEnabled(enabled) {
|
|
7956
|
+
mesh.showBoundingBox = enabled;
|
|
7957
|
+
},
|
|
7958
|
+
onChange: onChangeObservable,
|
|
7959
|
+
dispose: () => {
|
|
7960
|
+
showBoundingBoxHook.dispose();
|
|
7961
|
+
onChangeObservable.clear();
|
|
7962
|
+
},
|
|
7963
|
+
};
|
|
7964
|
+
},
|
|
7965
|
+
});
|
|
7814
7966
|
const abstractMeshVisibilityCommandRegistration = sceneExplorerService.addCommand({
|
|
7815
7967
|
predicate: (entity) => entity instanceof AbstractMesh && entity.getTotalVertices() > 0,
|
|
7968
|
+
order: 1100 /* DefaultCommandsOrder.MeshVisibility */,
|
|
7816
7969
|
getCommand: (mesh) => {
|
|
7817
7970
|
const onChangeObservable = new Observable();
|
|
7818
7971
|
const isVisibleHook = InterceptProperty(mesh, "isVisible", {
|
|
@@ -7840,6 +7993,7 @@ const NodeExplorerServiceDefinition = {
|
|
|
7840
7993
|
});
|
|
7841
7994
|
const activeCameraCommandRegistration = sceneExplorerService.addCommand({
|
|
7842
7995
|
predicate: (entity) => entity instanceof Camera,
|
|
7996
|
+
order: 700 /* DefaultCommandsOrder.CameraActive */,
|
|
7843
7997
|
getCommand: (camera) => {
|
|
7844
7998
|
const scene = camera.getScene();
|
|
7845
7999
|
const onChangeObservable = new Observable();
|
|
@@ -7871,6 +8025,7 @@ const NodeExplorerServiceDefinition = {
|
|
|
7871
8025
|
function addGizmoCommand(nodeClass, getGizmoRef) {
|
|
7872
8026
|
return sceneExplorerService.addCommand({
|
|
7873
8027
|
predicate: (entity) => entity instanceof nodeClass,
|
|
8028
|
+
order: 800 /* DefaultCommandsOrder.GizmoActive */,
|
|
7874
8029
|
getCommand: (node) => {
|
|
7875
8030
|
const onChangeObservable = new Observable();
|
|
7876
8031
|
let gizmoRef = null;
|
|
@@ -7879,7 +8034,7 @@ const NodeExplorerServiceDefinition = {
|
|
|
7879
8034
|
get displayName() {
|
|
7880
8035
|
return `Turn ${gizmoRef ? "Off" : "On"} Gizmo`;
|
|
7881
8036
|
},
|
|
7882
|
-
icon: () => (gizmoRef ? jsx(
|
|
8037
|
+
icon: () => (gizmoRef ? jsx(EyeRegular, {}) : jsx(EyeOffRegular, {})),
|
|
7883
8038
|
get isEnabled() {
|
|
7884
8039
|
return !!gizmoRef;
|
|
7885
8040
|
},
|
|
@@ -7909,6 +8064,7 @@ const NodeExplorerServiceDefinition = {
|
|
|
7909
8064
|
const cameraGizmoCommandRegistration = addGizmoCommand(Camera, gizmoService.getCameraGizmo.bind(gizmoService));
|
|
7910
8065
|
const lightEnabledCommandRegistration = sceneExplorerService.addCommand({
|
|
7911
8066
|
predicate: (entity) => entity instanceof Light,
|
|
8067
|
+
order: 700 /* DefaultCommandsOrder.LightActive */,
|
|
7912
8068
|
getCommand: (light) => {
|
|
7913
8069
|
return {
|
|
7914
8070
|
type: "toggle",
|
|
@@ -7930,6 +8086,7 @@ const NodeExplorerServiceDefinition = {
|
|
|
7930
8086
|
return {
|
|
7931
8087
|
dispose: () => {
|
|
7932
8088
|
sectionRegistration.dispose();
|
|
8089
|
+
abstractMeshBoundingBoxCommandRegistration.dispose();
|
|
7933
8090
|
abstractMeshVisibilityCommandRegistration.dispose();
|
|
7934
8091
|
activeCameraCommandRegistration.dispose();
|
|
7935
8092
|
cameraGizmoCommandRegistration.dispose();
|
|
@@ -8142,6 +8299,7 @@ const SpriteManagerExplorerServiceDefinition = {
|
|
|
8142
8299
|
});
|
|
8143
8300
|
const spritePlayStopCommandRegistration = sceneExplorerService.addCommand({
|
|
8144
8301
|
predicate: (entity) => entity instanceof Sprite,
|
|
8302
|
+
order: 600 /* DefaultCommandsOrder.SpritePlay */,
|
|
8145
8303
|
getCommand: (sprite) => {
|
|
8146
8304
|
const onChangeObservable = new Observable();
|
|
8147
8305
|
const playHook = InterceptFunction(sprite, "playAnimation", {
|