@babylonjs/inspector 8.30.3-preview → 8.30.4-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-BaLg4gki.js → captureService-Br4kaEaT.js} +2 -1
- package/lib/{captureService-BaLg4gki.js.map → captureService-Br4kaEaT.js.map} +1 -1
- package/lib/{exportService-DEj9QNTe.js → exportService-nwkeBa_W.js} +2 -1
- package/lib/{exportService-DEj9QNTe.js.map → exportService-nwkeBa_W.js.map} +1 -1
- package/lib/{importService-BoR1TPvc.js → importService-DtPZclnY.js} +2 -1
- package/lib/{importService-BoR1TPvc.js.map → importService-DtPZclnY.js.map} +1 -1
- package/lib/index.d.ts +2 -1
- package/lib/index.js +381 -117
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -3,7 +3,7 @@ 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, Body1Stronger, Checkbox as Checkbox$1, Body1, Accordion as Accordion$1, AccordionItem, AccordionHeader, Subtitle2Stronger, AccordionPanel, Divider, mergeClasses, TeachingPopover, TeachingPopoverSurface, TeachingPopoverHeader, TeachingPopoverBody, Body1Strong, TabList, Tooltip, Title3, Tab, SearchBox as SearchBox$1, FlatTree, FlatTreeItem, TreeItemLayout, Menu, MenuTrigger, MenuPopover, MenuList, MenuItem, Switch as Switch$1, PresenceBadge, Spinner, Dialog, DialogTrigger, DialogSurface, DialogBody, DialogTitle, DialogContent, SplitButton, MenuItemRadio, createLightTheme, createDarkTheme, FluentProvider, DialogActions, List as List$1, ListItem, useId, Input, SpinButton as SpinButton$1, Slider, MessageBar as MessageBar$1, MessageBarBody, MessageBarTitle, Badge, Popover, PopoverTrigger, ColorSwatch, PopoverSurface, ColorPicker, ColorArea, ColorSlider, AlphaSlider,
|
|
6
|
+
import { makeStyles, ToggleButton as ToggleButton$1, Button as Button$1, tokens, Link, InfoLabel as InfoLabel$1, Body1Stronger, Checkbox as Checkbox$1, Body1, Accordion as Accordion$1, AccordionItem, AccordionHeader, Subtitle2Stronger, AccordionPanel, Divider, mergeClasses, TeachingPopover, TeachingPopoverSurface, TeachingPopoverHeader, TeachingPopoverBody, Body1Strong, TabList, Tooltip, Title3, Tab, SearchBox as SearchBox$1, FlatTree, FlatTreeItem, TreeItemLayout, Menu, MenuTrigger, MenuPopover, MenuList, MenuItem, Switch as Switch$1, PresenceBadge, Spinner, Dialog, DialogTrigger, DialogSurface, DialogBody, DialogTitle, DialogContent, SplitButton, MenuItemRadio, createLightTheme, createDarkTheme, FluentProvider, 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, Toolbar as Toolbar$1, ToolbarButton, useComboboxFilter, Combobox, Field } from '@fluentui/react-components';
|
|
7
7
|
export { Link } from '@fluentui/react-components';
|
|
8
8
|
import { ChevronCircleRight20Regular, ChevronCircleDown20Regular, CopyRegular, PanelLeftExpandRegular, PanelLeftContractRegular, PanelRightExpandRegular, PanelRightContractRegular, DocumentTextRegular, FilterRegular, MoviesAndTvRegular, CubeTreeRegular, BugRegular, SettingsRegular, ArrowUploadRegular, DataBarHorizontalRegular, WrenchRegular, AppsAddInRegular, DismissRegular, WeatherSunnyRegular, WeatherMoonRegular, ErrorCircleRegular, ArrowMoveRegular, ArrowRotateClockwiseRegular, ArrowExpandRegular, SelectObjectRegular, CubeRegular, GlobeRegular, SaveRegular, ArrowUndoRegular, ClearFormattingRegular, DeleteRegular, EyeOffFilled, EyeFilled, ArrowMoveFilled, StopFilled, PlayFilled, StackRegular, FilmstripRegular, PauseFilled, WeatherSunnyLowFilled, LayerRegular, FrameRegular, PlayRegular, AppGenericRegular, PaintBrushRegular, BoxRegular, BranchRegular, CameraRegular, LightbulbRegular, EyeRegular, EyeOffRegular, VideoFilled, VideoRegular, FlashlightRegular, FlashlightOffRegular, Cone16Filled, Cone16Regular, 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';
|
|
@@ -97,6 +97,7 @@ import { BaseTexture } from '@babylonjs/core/Materials/Textures/baseTexture.js';
|
|
|
97
97
|
import { MultiRenderTarget } from '@babylonjs/core/Materials/Textures/multiRenderTarget.js';
|
|
98
98
|
import { RenderTargetTexture } from '@babylonjs/core/Materials/Textures/renderTargetTexture.js';
|
|
99
99
|
import { ThinTexture } from '@babylonjs/core/Materials/Textures/thinTexture.js';
|
|
100
|
+
import { WhenTextureReadyAsync, GetTextureDataAsync } from '@babylonjs/core/Misc/textureTools.js';
|
|
100
101
|
import '@babylonjs/core/PostProcesses/RenderPipeline/postProcessRenderPipelineManagerSceneComponent.js';
|
|
101
102
|
import '@babylonjs/core/Sprites/spriteSceneComponent.js';
|
|
102
103
|
import { DynamicTexture } from '@babylonjs/core/Materials/Textures/dynamicTexture.js';
|
|
@@ -605,6 +606,7 @@ const useCollapseStyles = makeStyles({
|
|
|
605
606
|
* @returns
|
|
606
607
|
*/
|
|
607
608
|
const Collapse = (props) => {
|
|
609
|
+
Collapse.displayName = "Collapse";
|
|
608
610
|
const classes = useCollapseStyles();
|
|
609
611
|
return (jsx(Collapse$1, { visible: props.visible, orientation: props.orientation, children: jsx("div", { className: `${classes.collapseContent} ${props.orientation === "horizontal" ? classes.horizontal : classes.vertical}`, children: props.children }) }));
|
|
610
612
|
};
|
|
@@ -640,6 +642,7 @@ const ToolContext = createContext({ useFluent: false, disableCopy: false, toolNa
|
|
|
640
642
|
* @returns
|
|
641
643
|
*/
|
|
642
644
|
const ToggleButton = (props) => {
|
|
645
|
+
ToggleButton.displayName = "ToggleButton";
|
|
643
646
|
const { value, onChange, title, appearance = "subtle" } = props;
|
|
644
647
|
const [checked, setChecked] = useState(value);
|
|
645
648
|
const toggle = useCallback(() => {
|
|
@@ -656,6 +659,7 @@ const ToggleButton = (props) => {
|
|
|
656
659
|
};
|
|
657
660
|
|
|
658
661
|
const Button = (props) => {
|
|
662
|
+
Button.displayName = "Button";
|
|
659
663
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
660
664
|
const { icon: Icon, label, ...buttonProps } = props;
|
|
661
665
|
return (jsx(Button$1, { iconPosition: "after", ...buttonProps, icon: Icon && jsx(Icon, {}), children: label && props.label }));
|
|
@@ -671,8 +675,15 @@ const CustomTokens = {
|
|
|
671
675
|
};
|
|
672
676
|
const UniformWidthStyling = { width: CustomTokens.inputWidth, textAlign: "right", boxSizing: "border-box" };
|
|
673
677
|
const useInputStyles$1 = makeStyles({
|
|
674
|
-
|
|
675
|
-
|
|
678
|
+
input: UniformWidthStyling,
|
|
679
|
+
invalid: { backgroundColor: tokens.colorPaletteRedBackground2 },
|
|
680
|
+
container: {
|
|
681
|
+
flex: 1,
|
|
682
|
+
display: "flex",
|
|
683
|
+
flexDirection: "column",
|
|
684
|
+
justifyContent: "center", // align items vertically
|
|
685
|
+
gap: "4px",
|
|
686
|
+
},
|
|
676
687
|
});
|
|
677
688
|
function HandleOnBlur(event) {
|
|
678
689
|
event.stopPropagation();
|
|
@@ -732,6 +743,7 @@ const usePropertyLineStyles = makeStyles({
|
|
|
732
743
|
*
|
|
733
744
|
*/
|
|
734
745
|
const PropertyLine = forwardRef((props, ref) => {
|
|
746
|
+
PropertyLine.displayName = "PropertyLine";
|
|
735
747
|
const classes = usePropertyLineStyles();
|
|
736
748
|
const { label, onCopy, expandedContent, children, nullable, ignoreNullable } = props;
|
|
737
749
|
const [expanded, setExpanded] = useState("expandByDefault" in props ? props.expandByDefault : false);
|
|
@@ -775,6 +787,7 @@ const PlaceholderPropertyLine = (props) => {
|
|
|
775
787
|
* @returns property-line wrapped link
|
|
776
788
|
*/
|
|
777
789
|
const LinkPropertyLine = (props) => {
|
|
790
|
+
LinkPropertyLine.displayName = "LinkPropertyLine";
|
|
778
791
|
return (jsx(PropertyLine, { ...props, children: jsx(Link, { inline: true, onClick: () => props.onLink?.(), href: props.url, title: props.title, children: jsx(Body1, { children: props.value }) }) }));
|
|
779
792
|
};
|
|
780
793
|
|
|
@@ -793,7 +806,7 @@ const LinkToEntityPropertyLine = (props) => {
|
|
|
793
806
|
!linkedEntity.reservedDataStore?.hidden && jsx(LinkPropertyLine, { ...rest, value: linkedEntity.name, onLink: () => (selectionService.selectedEntity = linkedEntity) }));
|
|
794
807
|
};
|
|
795
808
|
|
|
796
|
-
const useStyles$
|
|
809
|
+
const useStyles$g = makeStyles({
|
|
797
810
|
accordion: {
|
|
798
811
|
overflowX: "hidden",
|
|
799
812
|
overflowY: "auto",
|
|
@@ -813,11 +826,13 @@ const useStyles$f = makeStyles({
|
|
|
813
826
|
},
|
|
814
827
|
});
|
|
815
828
|
const AccordionSection = (props) => {
|
|
816
|
-
|
|
829
|
+
AccordionSection.displayName = "AccordionSection";
|
|
830
|
+
const classes = useStyles$g();
|
|
817
831
|
return jsx("div", { className: classes.panelDiv, children: props.children });
|
|
818
832
|
};
|
|
819
833
|
const Accordion = (props) => {
|
|
820
|
-
|
|
834
|
+
Accordion.displayName = "Accordion";
|
|
835
|
+
const classes = useStyles$g();
|
|
821
836
|
const { children, ...rest } = props;
|
|
822
837
|
const validChildren = useMemo(() => {
|
|
823
838
|
return (Children.map(children, (child) => {
|
|
@@ -867,7 +882,7 @@ function AsReadonlyArray(array) {
|
|
|
867
882
|
return array;
|
|
868
883
|
}
|
|
869
884
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
870
|
-
const useStyles$
|
|
885
|
+
const useStyles$f = makeStyles({
|
|
871
886
|
rootDiv: {
|
|
872
887
|
flex: 1,
|
|
873
888
|
overflow: "hidden",
|
|
@@ -876,7 +891,7 @@ const useStyles$e = makeStyles({
|
|
|
876
891
|
},
|
|
877
892
|
});
|
|
878
893
|
function ExtensibleAccordion(props) {
|
|
879
|
-
const classes = useStyles$
|
|
894
|
+
const classes = useStyles$f();
|
|
880
895
|
const { children, sections, sectionContent, context } = props;
|
|
881
896
|
const defaultSections = useMemo(() => {
|
|
882
897
|
const defaultSections = [];
|
|
@@ -964,7 +979,7 @@ function ExtensibleAccordion(props) {
|
|
|
964
979
|
})] })) }));
|
|
965
980
|
}
|
|
966
981
|
|
|
967
|
-
const useStyles$
|
|
982
|
+
const useStyles$e = makeStyles({
|
|
968
983
|
paneRootDiv: {
|
|
969
984
|
display: "flex",
|
|
970
985
|
flex: 1,
|
|
@@ -977,12 +992,12 @@ const useStyles$d = makeStyles({
|
|
|
977
992
|
*/
|
|
978
993
|
const SidePaneContainer = forwardRef((props, ref) => {
|
|
979
994
|
const { className, ...rest } = props;
|
|
980
|
-
const classes = useStyles$
|
|
995
|
+
const classes = useStyles$e();
|
|
981
996
|
return (jsx("div", { className: mergeClasses(classes.paneRootDiv, className), ref: ref, ...rest, children: props.children }));
|
|
982
997
|
});
|
|
983
998
|
|
|
984
999
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
985
|
-
const useStyles$
|
|
1000
|
+
const useStyles$d = makeStyles({
|
|
986
1001
|
extensionTeachingPopover: {
|
|
987
1002
|
maxWidth: "320px",
|
|
988
1003
|
},
|
|
@@ -993,7 +1008,7 @@ const useStyles$c = makeStyles({
|
|
|
993
1008
|
* @returns The teaching moment popover.
|
|
994
1009
|
*/
|
|
995
1010
|
const TeachingMoment = ({ shouldDisplay, positioningRef, onOpenChange, title, description }) => {
|
|
996
|
-
const classes = useStyles$
|
|
1011
|
+
const classes = useStyles$d();
|
|
997
1012
|
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 })] }) }));
|
|
998
1013
|
};
|
|
999
1014
|
|
|
@@ -1280,13 +1295,13 @@ function ConstructorFactory(constructor) {
|
|
|
1280
1295
|
}
|
|
1281
1296
|
|
|
1282
1297
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
1283
|
-
const useStyles$
|
|
1298
|
+
const useStyles$c = makeStyles({
|
|
1284
1299
|
placeholderDiv: {
|
|
1285
1300
|
padding: `${tokens.spacingVerticalM} ${tokens.spacingHorizontalM}`,
|
|
1286
1301
|
},
|
|
1287
1302
|
});
|
|
1288
1303
|
const PropertiesPane = (props) => {
|
|
1289
|
-
const classes = useStyles$
|
|
1304
|
+
const classes = useStyles$c();
|
|
1290
1305
|
const entity = props.context;
|
|
1291
1306
|
return entity != null ? (jsx(ExtensibleAccordion, { ...props })) : (jsx("div", { className: classes.placeholderDiv, children: jsx(Body1Strong, { italic: true, children: "No entity selected." }) }));
|
|
1292
1307
|
};
|
|
@@ -1329,7 +1344,7 @@ const SelectionServiceDefinition = {
|
|
|
1329
1344
|
const RootComponentServiceIdentity = Symbol("RootComponent");
|
|
1330
1345
|
const ShellServiceIdentity = Symbol("ShellService");
|
|
1331
1346
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
1332
|
-
const useStyles$
|
|
1347
|
+
const useStyles$b = makeStyles({
|
|
1333
1348
|
mainView: {
|
|
1334
1349
|
flex: 1,
|
|
1335
1350
|
display: "flex",
|
|
@@ -1452,7 +1467,7 @@ const useStyles$a = makeStyles({
|
|
|
1452
1467
|
});
|
|
1453
1468
|
// 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.
|
|
1454
1469
|
const ToolbarItem = ({ location, alignment, id, component: Component, displayName: displayName, suppressTeachingMoment }) => {
|
|
1455
|
-
const classes = useStyles$
|
|
1470
|
+
const classes = useStyles$b();
|
|
1456
1471
|
const useTeachingMoment = useMemo(() => MakePopoverTeachingMoment(`Bar/${location}/${alignment}/${displayName ?? id}`), [displayName, id]);
|
|
1457
1472
|
const teachingMoment = useTeachingMoment(suppressTeachingMoment);
|
|
1458
1473
|
return (jsxs(Fragment, { children: [jsx(TeachingMoment, { ...teachingMoment, shouldDisplay: teachingMoment.shouldDisplay && !suppressTeachingMoment, title: displayName ?? "Extension", description: `The "${displayName ?? id}" extension can be accessed here.` }), jsx("div", { className: classes.barItem, ref: teachingMoment.targetRef, children: jsx(Component, {}) })] }));
|
|
@@ -1460,7 +1475,7 @@ const ToolbarItem = ({ location, alignment, id, component: Component, displayNam
|
|
|
1460
1475
|
// TODO: Handle overflow, possibly via https://react.fluentui.dev/?path=/docs/components-overflow--docs with priority.
|
|
1461
1476
|
// This component just renders a toolbar with left aligned toolbar items on the left and right aligned toolbar items on the right.
|
|
1462
1477
|
const Toolbar = ({ location, components }) => {
|
|
1463
|
-
const classes = useStyles$
|
|
1478
|
+
const classes = useStyles$b();
|
|
1464
1479
|
const leftComponents = useMemo(() => components.filter((entry) => entry.horizontalLocation === "left"), [components]);
|
|
1465
1480
|
const rightComponents = useMemo(() => components.filter((entry) => entry.horizontalLocation === "right"), [components]);
|
|
1466
1481
|
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, { 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))) })] })) }));
|
|
@@ -1469,7 +1484,7 @@ const Toolbar = ({ location, components }) => {
|
|
|
1469
1484
|
const SidePaneTab = ({ alignment, id,
|
|
1470
1485
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
1471
1486
|
icon: Icon, title, suppressTeachingMoment, }) => {
|
|
1472
|
-
const classes = useStyles$
|
|
1487
|
+
const classes = useStyles$b();
|
|
1473
1488
|
const useTeachingMoment = useMemo(() => MakePopoverTeachingMoment(`Pane/${alignment}/${title ?? id}`), [title, id]);
|
|
1474
1489
|
const teachingMoment = useTeachingMoment(suppressTeachingMoment);
|
|
1475
1490
|
return (jsxs(Fragment, { children: [jsx(TeachingMoment, { ...teachingMoment, shouldDisplay: teachingMoment.shouldDisplay && !suppressTeachingMoment, title: title ?? "Extension", description: `The "${title ?? id}" extension can be accessed here.` }), jsx(Tab, { ref: teachingMoment.targetRef, className: classes.tab, value: id, icon: jsx(Tooltip, { content: title ?? id, relationship: "description", children: jsx(Icon, {}) }) }, id)] }));
|
|
@@ -1478,7 +1493,7 @@ icon: Icon, title, suppressTeachingMoment, }) => {
|
|
|
1478
1493
|
// In "compact" mode, the tab list is integrated into the pane itself.
|
|
1479
1494
|
// In "full" mode, the returned tab list is later injected into the toolbar.
|
|
1480
1495
|
function usePane(alignment, defaultWidth, minWidth, topPanes, bottomPanes, toolbarMode, topBarItems, bottomBarItems) {
|
|
1481
|
-
const classes = useStyles$
|
|
1496
|
+
const classes = useStyles$b();
|
|
1482
1497
|
const [topSelectedTab, setTopSelectedTab] = useState();
|
|
1483
1498
|
const [bottomSelectedTab, setBottomSelectedTab] = useState();
|
|
1484
1499
|
const [collapsed, setCollapsed] = useState(false);
|
|
@@ -1590,7 +1605,7 @@ function MakeShellServiceDefinition({ leftPaneDefaultWidth = 350, leftPaneMinWid
|
|
|
1590
1605
|
const bottomRightPaneCollection = new ObservableCollection();
|
|
1591
1606
|
const centralContentCollection = new ObservableCollection();
|
|
1592
1607
|
const rootComponent = () => {
|
|
1593
|
-
const classes = useStyles$
|
|
1608
|
+
const classes = useStyles$b();
|
|
1594
1609
|
const topBarItems = useOrderedObservableCollection(topBarItemCollection);
|
|
1595
1610
|
const bottomBarItems = useOrderedObservableCollection(bottomBarItemCollection);
|
|
1596
1611
|
const topLeftPanes = useOrderedObservableCollection(topLeftPaneCollection);
|
|
@@ -1824,7 +1839,7 @@ function ExpandOrCollapseAll(treeItem, open, openItems) {
|
|
|
1824
1839
|
TraverseGraph([treeItem], (treeItem) => treeItem.children, (treeItem) => addOrRemove(treeItem.type === "entity" ? treeItem.entity.uniqueId : treeItem.sectionName));
|
|
1825
1840
|
}
|
|
1826
1841
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
1827
|
-
const useStyles$
|
|
1842
|
+
const useStyles$a = makeStyles({
|
|
1828
1843
|
rootDiv: {
|
|
1829
1844
|
flex: 1,
|
|
1830
1845
|
overflow: "hidden",
|
|
@@ -1859,7 +1874,7 @@ const ToggleCommand = (props) => {
|
|
|
1859
1874
|
};
|
|
1860
1875
|
const SceneTreeItem = (props) => {
|
|
1861
1876
|
const { isSelected, select } = props;
|
|
1862
|
-
const classes = useStyles$
|
|
1877
|
+
const classes = useStyles$a();
|
|
1863
1878
|
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(MoviesAndTvRegular, {}), className: classes.sceneTreeItemLayout, style: isSelected ? { backgroundColor: tokens.colorNeutralBackground1Selected } : undefined, children: jsx(Body1Strong, { wrap: false, truncate: true, children: "Scene" }) }) }, "scene"));
|
|
1864
1879
|
};
|
|
1865
1880
|
const SectionTreeItem = (props) => {
|
|
@@ -1920,7 +1935,7 @@ const EntityTreeItem = (props) => {
|
|
|
1920
1935
|
}, children: jsx(Body1, { wrap: false, truncate: true, children: name.substring(0, 100) }) }) }, entityItem.entity.uniqueId) }), jsx(MenuPopover, { hidden: !entityItem.children?.length, children: jsxs(MenuList, { children: [jsx(MenuItem, { onClick: expandAll, children: jsx(Body1, { children: "Expand All" }) }), jsx(MenuItem, { onClick: collapseAll, children: jsx(Body1, { children: "Collapse All" }) })] }) })] }));
|
|
1921
1936
|
};
|
|
1922
1937
|
const SceneExplorer = (props) => {
|
|
1923
|
-
const classes = useStyles$
|
|
1938
|
+
const classes = useStyles$a();
|
|
1924
1939
|
const { sections, commandProviders, scene, selectedEntity } = props;
|
|
1925
1940
|
const [openItems, setOpenItems] = useState(new Set());
|
|
1926
1941
|
const [sceneVersion, setSceneVersion] = useState(0);
|
|
@@ -2210,6 +2225,7 @@ const useSwitchStyles = makeStyles({
|
|
|
2210
2225
|
* @returns Switch component
|
|
2211
2226
|
*/
|
|
2212
2227
|
const Switch = (props) => {
|
|
2228
|
+
Switch.displayName = "Switch";
|
|
2213
2229
|
const classes = useSwitchStyles();
|
|
2214
2230
|
const [checked, setChecked] = useState(() => props.value ?? false);
|
|
2215
2231
|
useEffect(() => {
|
|
@@ -2230,6 +2246,7 @@ const Switch = (props) => {
|
|
|
2230
2246
|
* @returns A React element representing the property line with a switch
|
|
2231
2247
|
*/
|
|
2232
2248
|
const SwitchPropertyLine = (props) => {
|
|
2249
|
+
SwitchPropertyLine.displayName = "SwitchPropertyLine";
|
|
2233
2250
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
2234
2251
|
const { label, ...switchProps } = props;
|
|
2235
2252
|
// Ensure the label gets passed to the PropertyLine component and not to the underlying switch
|
|
@@ -2464,6 +2481,7 @@ const SettingsServiceDefinition = {
|
|
|
2464
2481
|
* @returns
|
|
2465
2482
|
*/
|
|
2466
2483
|
const StringifiedPropertyLine = (props) => {
|
|
2484
|
+
StringifiedPropertyLine.displayName = "StringifiedPropertyLine";
|
|
2467
2485
|
const value = props.precision !== undefined ? props.value.toFixed(props.precision) : props.value.toLocaleString();
|
|
2468
2486
|
const withUnits = props.units ? `${value} ${props.units}` : value;
|
|
2469
2487
|
return (jsx(PropertyLine, { ...props, children: jsx(Body1, { title: props.title, children: withUnits }) }));
|
|
@@ -2529,10 +2547,12 @@ const FrameStepsStats = ({ context: scene }) => {
|
|
|
2529
2547
|
* @returns A button inside a line
|
|
2530
2548
|
*/
|
|
2531
2549
|
const ButtonLine = (props) => {
|
|
2550
|
+
ButtonLine.displayName = "ButtonLine";
|
|
2532
2551
|
return (jsx(LineContainer, { children: jsx(Button, { ...props }) }));
|
|
2533
2552
|
};
|
|
2534
2553
|
|
|
2535
2554
|
const FileUploadLine = (props) => {
|
|
2555
|
+
FileUploadLine.displayName = "FileUploadLine";
|
|
2536
2556
|
const inputRef = useRef(null);
|
|
2537
2557
|
const handleButtonClick = () => {
|
|
2538
2558
|
inputRef.current?.click();
|
|
@@ -2655,18 +2675,19 @@ const PerformanceStats = ({ context: scene }) => {
|
|
|
2655
2675
|
* @returns property-line wrapped text
|
|
2656
2676
|
*/
|
|
2657
2677
|
const TextPropertyLine = (props) => {
|
|
2678
|
+
TextPropertyLine.displayName = "TextPropertyLine";
|
|
2658
2679
|
const { value, title } = props;
|
|
2659
2680
|
return (jsx(PropertyLine, { ...props, children: jsx(Body1, { title: title, children: value }) }));
|
|
2660
2681
|
};
|
|
2661
2682
|
|
|
2662
|
-
const useStyles$
|
|
2683
|
+
const useStyles$9 = makeStyles({
|
|
2663
2684
|
pinnedStatsPane: {
|
|
2664
2685
|
flex: "0 1 auto",
|
|
2665
2686
|
paddingBottom: tokens.spacingHorizontalM,
|
|
2666
2687
|
},
|
|
2667
2688
|
});
|
|
2668
2689
|
const StatsPane = (props) => {
|
|
2669
|
-
const classes = useStyles$
|
|
2690
|
+
const classes = useStyles$9();
|
|
2670
2691
|
const scene = props.context;
|
|
2671
2692
|
const engine = scene.getEngine();
|
|
2672
2693
|
const fps = useObservableState(() => Math.round(engine.getFps()), engine.onBeginFrameObservable);
|
|
@@ -2678,7 +2699,10 @@ const StatsPane = (props) => {
|
|
|
2678
2699
|
* @param props - The properties for the PropertyLine, including the boolean value to display.
|
|
2679
2700
|
* @returns A PropertyLine component with a PresenceBadge indicating the boolean state.
|
|
2680
2701
|
*/
|
|
2681
|
-
const BooleanBadgePropertyLine = (props) =>
|
|
2702
|
+
const BooleanBadgePropertyLine = (props) => {
|
|
2703
|
+
BooleanBadgePropertyLine.displayName = "BooleanBadgePropertyLine";
|
|
2704
|
+
return (jsx(PropertyLine, { ...props, children: jsx(PresenceBadge, { status: props.value ? "available" : "do-not-disturb", outOfOffice: true }) }));
|
|
2705
|
+
};
|
|
2682
2706
|
|
|
2683
2707
|
const SystemStats = ({ context: scene }) => {
|
|
2684
2708
|
const engine = scene.getEngine();
|
|
@@ -2834,19 +2858,19 @@ const DefaultInspectorExtensionFeed = new BuiltInsExtensionFeed("Inspector", [
|
|
|
2834
2858
|
name: "Export Tools",
|
|
2835
2859
|
description: "Adds new features to enable exporting Babylon assets such as .gltf, .glb, .babylon, and more.",
|
|
2836
2860
|
keywords: ["export", "gltf", "glb", "babylon", "exporter", "tools"],
|
|
2837
|
-
getExtensionModuleAsync: async () => await import('./exportService-
|
|
2861
|
+
getExtensionModuleAsync: async () => await import('./exportService-nwkeBa_W.js'),
|
|
2838
2862
|
},
|
|
2839
2863
|
{
|
|
2840
2864
|
name: "Capture Tools",
|
|
2841
2865
|
description: "Adds new features to enable capturing screenshots, GIFs, videos, and more.",
|
|
2842
2866
|
keywords: ["capture", "screenshot", "gif", "video", "tools"],
|
|
2843
|
-
getExtensionModuleAsync: async () => await import('./captureService-
|
|
2867
|
+
getExtensionModuleAsync: async () => await import('./captureService-Br4kaEaT.js'),
|
|
2844
2868
|
},
|
|
2845
2869
|
{
|
|
2846
2870
|
name: "Import Tools",
|
|
2847
2871
|
description: "Adds new features related to importing Babylon assets.",
|
|
2848
2872
|
keywords: ["import", "tools"],
|
|
2849
|
-
getExtensionModuleAsync: async () => await import('./importService-
|
|
2873
|
+
getExtensionModuleAsync: async () => await import('./importService-DtPZclnY.js'),
|
|
2850
2874
|
},
|
|
2851
2875
|
]);
|
|
2852
2876
|
|
|
@@ -3288,7 +3312,7 @@ class ServiceContainer {
|
|
|
3288
3312
|
}
|
|
3289
3313
|
|
|
3290
3314
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
3291
|
-
const useStyles$
|
|
3315
|
+
const useStyles$8 = makeStyles({
|
|
3292
3316
|
extensionButton: {},
|
|
3293
3317
|
extensionsDialogSurface: {
|
|
3294
3318
|
height: "auto",
|
|
@@ -3333,7 +3357,7 @@ const useStyles$7 = makeStyles({
|
|
|
3333
3357
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
3334
3358
|
const useTeachingMoment = MakePopoverTeachingMoment("Extensions");
|
|
3335
3359
|
const ExtensionDetails = memo((props) => {
|
|
3336
|
-
const classes = useStyles$
|
|
3360
|
+
const classes = useStyles$8();
|
|
3337
3361
|
const [canInstall, setCanInstall] = useState(false);
|
|
3338
3362
|
const [canUninstall, setCanUninstall] = useState(false);
|
|
3339
3363
|
const [isStateChanging, setIsStateChanging] = useState(false);
|
|
@@ -3377,7 +3401,7 @@ const ExtensionListServiceDefinition = {
|
|
|
3377
3401
|
suppressTeachingMoment: true,
|
|
3378
3402
|
order: -200,
|
|
3379
3403
|
component: () => {
|
|
3380
|
-
const classes = useStyles$
|
|
3404
|
+
const classes = useStyles$8();
|
|
3381
3405
|
const [selectedTab, setSelectedTab] = useState("available");
|
|
3382
3406
|
const extensionManager = useExtensionManager();
|
|
3383
3407
|
const [extensions, setExtensions] = useState([]);
|
|
@@ -3406,7 +3430,7 @@ const ExtensionListServiceDefinition = {
|
|
|
3406
3430
|
},
|
|
3407
3431
|
};
|
|
3408
3432
|
|
|
3409
|
-
const useStyles$
|
|
3433
|
+
const useStyles$7 = makeStyles({
|
|
3410
3434
|
themeButton: {
|
|
3411
3435
|
margin: `${tokens.spacingVerticalXXS} 0`,
|
|
3412
3436
|
},
|
|
@@ -3425,7 +3449,7 @@ const ThemeSelectorServiceDefinition = {
|
|
|
3425
3449
|
suppressTeachingMoment: true,
|
|
3426
3450
|
order: -300,
|
|
3427
3451
|
component: () => {
|
|
3428
|
-
const classes = useStyles$
|
|
3452
|
+
const classes = useStyles$7();
|
|
3429
3453
|
const { isDarkMode, themeMode, setThemeMode } = useThemeMode();
|
|
3430
3454
|
const onSelectedThemeChange = useCallback((e, data) => {
|
|
3431
3455
|
setThemeMode(data.checkedItems.includes("System") ? "system" : data.checkedItems[0].toLocaleLowerCase());
|
|
@@ -3471,7 +3495,7 @@ const DarkTheme = {
|
|
|
3471
3495
|
};
|
|
3472
3496
|
|
|
3473
3497
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
3474
|
-
const useStyles$
|
|
3498
|
+
const useStyles$6 = makeStyles({
|
|
3475
3499
|
app: {
|
|
3476
3500
|
colorScheme: "light dark",
|
|
3477
3501
|
flexGrow: 1,
|
|
@@ -3504,7 +3528,7 @@ const useStyles$5 = makeStyles({
|
|
|
3504
3528
|
function MakeModularTool(options) {
|
|
3505
3529
|
const { containerElement, serviceDefinitions, themeMode, showThemeSelector = true, extensionFeeds = [] } = options;
|
|
3506
3530
|
const modularToolRootComponent = () => {
|
|
3507
|
-
const classes = useStyles$
|
|
3531
|
+
const classes = useStyles$6();
|
|
3508
3532
|
const [extensionManagerContext, setExtensionManagerContext] = useState();
|
|
3509
3533
|
const { isDarkMode } = useThemeMode(themeMode);
|
|
3510
3534
|
const [requiredExtensions, setRequiredExtensions] = useState();
|
|
@@ -3704,7 +3728,7 @@ const GizmoServiceDefinition = {
|
|
|
3704
3728
|
},
|
|
3705
3729
|
};
|
|
3706
3730
|
|
|
3707
|
-
const useStyles$
|
|
3731
|
+
const useStyles$5 = makeStyles({
|
|
3708
3732
|
coordinatesModeButton: {
|
|
3709
3733
|
margin: `0 ${tokens.spacingVerticalXS}`,
|
|
3710
3734
|
},
|
|
@@ -3714,7 +3738,7 @@ const useStyles$4 = makeStyles({
|
|
|
3714
3738
|
});
|
|
3715
3739
|
const GizmoToolbar = (props) => {
|
|
3716
3740
|
const { scene, entity, gizmoService } = props;
|
|
3717
|
-
const classes = useStyles$
|
|
3741
|
+
const classes = useStyles$5();
|
|
3718
3742
|
const gizmoManager = useResource(useCallback(() => {
|
|
3719
3743
|
const utilityLayerRef = gizmoService.getUtilityLayer(scene);
|
|
3720
3744
|
const keepDepthUtilityLayerRef = gizmoService.getUtilityLayer(scene, "keepDepth");
|
|
@@ -3840,10 +3864,12 @@ const TargetedAnimationGeneralProperties = (props) => {
|
|
|
3840
3864
|
* @returns
|
|
3841
3865
|
*/
|
|
3842
3866
|
const InfoLabel = (props) => {
|
|
3867
|
+
InfoLabel.displayName = "InfoLabel";
|
|
3843
3868
|
return (jsx(InfoLabel$1, { htmlFor: props.htmlFor, info: props.info, children: jsx(Body1, { children: props.label }) }));
|
|
3844
3869
|
};
|
|
3845
3870
|
|
|
3846
3871
|
const TextInput = (props) => {
|
|
3872
|
+
TextInput.displayName = "TextInput";
|
|
3847
3873
|
const classes = useInputStyles$1();
|
|
3848
3874
|
const [value, setValue] = useState(props.value);
|
|
3849
3875
|
const lastCommittedValue = useRef(props.value);
|
|
@@ -3874,11 +3900,13 @@ const TextInput = (props) => {
|
|
|
3874
3900
|
setValue(event.currentTarget.value);
|
|
3875
3901
|
tryCommitValue(event.currentTarget.value);
|
|
3876
3902
|
};
|
|
3903
|
+
const mergedClassName = mergeClasses(classes.input, !validateValue(value) ? classes.invalid : "", props.className);
|
|
3877
3904
|
const id = useId("input-button");
|
|
3878
|
-
return (jsxs("div", { 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:
|
|
3905
|
+
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 })] }));
|
|
3879
3906
|
};
|
|
3880
3907
|
|
|
3881
3908
|
const SpinButton = (props) => {
|
|
3909
|
+
SpinButton.displayName = "SpinButton";
|
|
3882
3910
|
const classes = useInputStyles$1();
|
|
3883
3911
|
const { min, max } = props;
|
|
3884
3912
|
const [value, setValue] = useState(props.value);
|
|
@@ -3921,7 +3949,8 @@ const SpinButton = (props) => {
|
|
|
3921
3949
|
}
|
|
3922
3950
|
};
|
|
3923
3951
|
const id = useId("spin-button");
|
|
3924
|
-
|
|
3952
|
+
const mergedClassName = mergeClasses(classes.input, !validateValue(value) ? classes.invalid : "", props.className);
|
|
3953
|
+
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 })] }));
|
|
3925
3954
|
};
|
|
3926
3955
|
/**
|
|
3927
3956
|
* Fluent's CalculatePrecision function
|
|
@@ -3972,7 +4001,10 @@ function PrecisionRound(value, precision) {
|
|
|
3972
4001
|
* @param props - PropertyLineProps and InputProps
|
|
3973
4002
|
* @returns property-line wrapped input component
|
|
3974
4003
|
*/
|
|
3975
|
-
const TextInputPropertyLine = (props) =>
|
|
4004
|
+
const TextInputPropertyLine = (props) => {
|
|
4005
|
+
TextInputPropertyLine.displayName = "TextInputPropertyLine";
|
|
4006
|
+
return (jsx(PropertyLine, { ...props, children: jsx(TextInput, { ...props }) }));
|
|
4007
|
+
};
|
|
3976
4008
|
/**
|
|
3977
4009
|
* Wraps a number input in a property line
|
|
3978
4010
|
* To force integer values, use forceInt param (this is distinct from the 'step' param, which will still allow submitting an integer value. forceInt will not)
|
|
@@ -3980,6 +4012,7 @@ const TextInputPropertyLine = (props) => (jsx(PropertyLine, { ...props, children
|
|
|
3980
4012
|
* @returns property-line wrapped input component
|
|
3981
4013
|
*/
|
|
3982
4014
|
const NumberInputPropertyLine = (props) => {
|
|
4015
|
+
NumberInputPropertyLine.displayName = "NumberInputPropertyLine";
|
|
3983
4016
|
return (jsx(PropertyLine, { ...props, children: jsx(SpinButton, { ...props }) }));
|
|
3984
4017
|
};
|
|
3985
4018
|
|
|
@@ -4002,6 +4035,7 @@ const useSyncedSliderStyles = makeStyles({
|
|
|
4002
4035
|
* @returns SyncedSlider component
|
|
4003
4036
|
*/
|
|
4004
4037
|
const SyncedSliderInput = (props) => {
|
|
4038
|
+
SyncedSliderInput.displayName = "SyncedSliderInput";
|
|
4005
4039
|
const { infoLabel, ...passthroughProps } = props;
|
|
4006
4040
|
const classes = useSyncedSliderStyles();
|
|
4007
4041
|
const [value, setValue] = useState(props.value);
|
|
@@ -4051,6 +4085,7 @@ const SyncedSliderInput = (props) => {
|
|
|
4051
4085
|
* @returns
|
|
4052
4086
|
*/
|
|
4053
4087
|
const SyncedSliderPropertyLine = forwardRef((props, ref) => {
|
|
4088
|
+
SyncedSliderPropertyLine.displayName = "SyncedSliderPropertyLine";
|
|
4054
4089
|
const { label, description, ...sliderProps } = props;
|
|
4055
4090
|
return (jsx(PropertyLine, { ref: ref, ...props, children: jsx(SyncedSliderInput, { ...sliderProps }) }));
|
|
4056
4091
|
});
|
|
@@ -4130,6 +4165,7 @@ const useClasses = makeStyles({
|
|
|
4130
4165
|
},
|
|
4131
4166
|
});
|
|
4132
4167
|
const MessageBar = (props) => {
|
|
4168
|
+
MessageBar.displayName = "MessageBar";
|
|
4133
4169
|
const { message, title: header, intent, docLink } = props;
|
|
4134
4170
|
const classes = useClasses();
|
|
4135
4171
|
return (jsx("div", { className: classes.container, children: jsx(MessageBar$1, { intent: intent, layout: "multiline", children: jsxs(MessageBarBody, { children: [jsx(MessageBarTitle, { children: header }), message, docLink && (jsxs(Fragment, { children: [" - ", jsx(Link, { href: docLink, target: "_blank", rel: "noopener noreferrer", children: "Learn More" })] }))] }) }) }));
|
|
@@ -4237,6 +4273,7 @@ const HasW = (vector) => vector instanceof Vector4 || vector instanceof Quaterni
|
|
|
4237
4273
|
* @returns
|
|
4238
4274
|
*/
|
|
4239
4275
|
const TensorPropertyLine = (props) => {
|
|
4276
|
+
TensorPropertyLine.displayName = "TensorPropertyLine";
|
|
4240
4277
|
const converted = (val) => (props.valueConverter ? props.valueConverter.from(val) : val);
|
|
4241
4278
|
const formatted = (val) => converted(val).toFixed(props.step !== undefined ? CalculatePrecision(props.step) : 2);
|
|
4242
4279
|
const [vector, setVector] = useState(props.value);
|
|
@@ -4252,12 +4289,14 @@ const TensorPropertyLine = (props) => {
|
|
|
4252
4289
|
};
|
|
4253
4290
|
const ToDegreesConverter = { from: Tools.ToDegrees, to: Tools.ToRadians };
|
|
4254
4291
|
const RotationVectorPropertyLine = (props) => {
|
|
4292
|
+
RotationVectorPropertyLine.displayName = "RotationVectorPropertyLine";
|
|
4255
4293
|
const min = props.useDegrees ? 0 : undefined;
|
|
4256
4294
|
const max = props.useDegrees ? 360 : undefined;
|
|
4257
4295
|
return (jsx(Vector3PropertyLine, { ...props, unit: props.useDegrees ? "deg" : "rad", valueConverter: props.useDegrees ? ToDegreesConverter : undefined, min: min, max: max, step: 0.001 }));
|
|
4258
4296
|
};
|
|
4259
4297
|
const QuaternionPropertyLineInternal = TensorPropertyLine;
|
|
4260
4298
|
const QuaternionPropertyLine = (props) => {
|
|
4299
|
+
QuaternionPropertyLine.displayName = "QuaternionPropertyLine";
|
|
4261
4300
|
const min = props.useDegrees ? 0 : undefined;
|
|
4262
4301
|
const max = props.useDegrees ? 360 : undefined;
|
|
4263
4302
|
const [quat, setQuat] = useState(props.value);
|
|
@@ -4278,50 +4317,97 @@ const Vector2PropertyLine = TensorPropertyLine;
|
|
|
4278
4317
|
const Vector3PropertyLine = TensorPropertyLine;
|
|
4279
4318
|
const Vector4PropertyLine = TensorPropertyLine;
|
|
4280
4319
|
|
|
4281
|
-
const
|
|
4282
|
-
|
|
4283
|
-
|
|
4320
|
+
const useDropdownStyles = makeStyles({
|
|
4321
|
+
dropdown: { ...UniformWidthStyling, minWidth: CustomTokens.inputWidth },
|
|
4322
|
+
container: {
|
|
4284
4323
|
display: "flex",
|
|
4285
4324
|
flexDirection: "column",
|
|
4286
|
-
|
|
4325
|
+
justifyContent: "center", // align items vertically
|
|
4326
|
+
gap: "4px",
|
|
4327
|
+
},
|
|
4328
|
+
});
|
|
4329
|
+
/**
|
|
4330
|
+
* Renders a fluent UI dropdown component for the options passed in, and an additional 'Not Defined' option if null is set to true
|
|
4331
|
+
* This component can handle both null and undefined values
|
|
4332
|
+
* @param props
|
|
4333
|
+
* @returns dropdown component
|
|
4334
|
+
*/
|
|
4335
|
+
const Dropdown = (props) => {
|
|
4336
|
+
Dropdown.displayName = "Dropdown";
|
|
4337
|
+
const classes = useDropdownStyles();
|
|
4338
|
+
const { options, value } = props;
|
|
4339
|
+
const [defaultVal, setDefaultVal] = useState(props.value);
|
|
4340
|
+
useEffect(() => {
|
|
4341
|
+
setDefaultVal(value);
|
|
4342
|
+
}, [props.value]);
|
|
4343
|
+
const id = useId("dropdown");
|
|
4344
|
+
const mergedClassName = mergeClasses(classes.dropdown, props.className);
|
|
4345
|
+
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) => {
|
|
4346
|
+
const value = typeof props.value === "number" ? Number(data.optionValue) : data.optionValue;
|
|
4347
|
+
if (value !== undefined) {
|
|
4348
|
+
setDefaultVal(value);
|
|
4349
|
+
props.onChange(value);
|
|
4350
|
+
}
|
|
4351
|
+
}, selectedOptions: [defaultVal.toString()], value: options.find((o) => o.value === defaultVal)?.label, children: options.map((option) => (jsx(Option, { className: classes.dropdown, value: option.value.toString(), disabled: false, children: option.label }, option.label))) })] }));
|
|
4352
|
+
};
|
|
4353
|
+
const NumberDropdown = Dropdown;
|
|
4354
|
+
const StringDropdown = Dropdown;
|
|
4355
|
+
|
|
4356
|
+
const useColorPickerStyles = makeStyles({
|
|
4357
|
+
container: {
|
|
4358
|
+
width: "380px",
|
|
4359
|
+
display: "flex", // becomes a flexbox
|
|
4360
|
+
flexDirection: "column", // with children in a column
|
|
4361
|
+
alignItems: "center", // centers children horizontally
|
|
4362
|
+
justifyContent: "center", // centers children vertically (if height is set)
|
|
4363
|
+
borderRadius: "4px",
|
|
4364
|
+
gap: "15px",
|
|
4287
4365
|
overflow: "visible",
|
|
4288
4366
|
},
|
|
4367
|
+
row: {
|
|
4368
|
+
flex: 1, // is a row in the container's flex column
|
|
4369
|
+
display: "flex", // becomes its own flexbox
|
|
4370
|
+
flexDirection: "row", // with children in a row
|
|
4371
|
+
gap: "20px",
|
|
4372
|
+
alignItems: "center", // align items vertically
|
|
4373
|
+
width: "100%",
|
|
4374
|
+
},
|
|
4375
|
+
colorPicker: {
|
|
4376
|
+
flex: 1,
|
|
4377
|
+
width: "350px",
|
|
4378
|
+
height: "350px",
|
|
4379
|
+
},
|
|
4289
4380
|
previewColor: {
|
|
4290
|
-
width: "
|
|
4291
|
-
height: "
|
|
4292
|
-
borderRadius: tokens.borderRadiusMedium,
|
|
4381
|
+
width: "60px",
|
|
4382
|
+
height: "60px",
|
|
4383
|
+
borderRadius: tokens.borderRadiusMedium, // 4px?
|
|
4293
4384
|
border: `${tokens.spacingVerticalXXS} solid ${tokens.colorNeutralShadowKeyLighter}`,
|
|
4294
4385
|
"@media (forced-colors: active)": {
|
|
4295
4386
|
forcedColorAdjust: "none", // ensures elmement maintains color in high constrast mode
|
|
4296
4387
|
},
|
|
4297
4388
|
},
|
|
4298
|
-
|
|
4389
|
+
inputRow: {
|
|
4299
4390
|
display: "flex",
|
|
4300
4391
|
flexDirection: "row",
|
|
4301
|
-
|
|
4302
|
-
|
|
4392
|
+
flex: 1, // grow and fill available space
|
|
4393
|
+
justifyContent: "center",
|
|
4394
|
+
gap: "10px",
|
|
4395
|
+
width: "100%",
|
|
4303
4396
|
},
|
|
4304
|
-
|
|
4305
|
-
|
|
4306
|
-
|
|
4397
|
+
inputField: {
|
|
4398
|
+
flex: 1, // grow and fill available space
|
|
4399
|
+
width: "auto",
|
|
4400
|
+
minWidth: 0,
|
|
4307
4401
|
gap: tokens.spacingVerticalSNudge, // 6px
|
|
4308
4402
|
},
|
|
4309
|
-
input: {
|
|
4310
|
-
width: "80px",
|
|
4311
|
-
},
|
|
4312
|
-
spinButton: {
|
|
4313
|
-
width: "50px",
|
|
4314
|
-
},
|
|
4315
|
-
container: {
|
|
4316
|
-
display: "flex",
|
|
4317
|
-
flexDirection: "column",
|
|
4318
|
-
gap: tokens.spacingVerticalL, // 16px
|
|
4319
|
-
},
|
|
4320
4403
|
});
|
|
4321
4404
|
const ColorPickerPopup = (props) => {
|
|
4405
|
+
ColorPickerPopup.displayName = "ColorPickerPopup";
|
|
4322
4406
|
const classes = useColorPickerStyles();
|
|
4323
4407
|
const [color, setColor] = useState(props.value);
|
|
4324
4408
|
const [popoverOpen, setPopoverOpen] = useState(false);
|
|
4409
|
+
const [isLinear, setIsLinear] = useState(props.isLinearMode ?? false);
|
|
4410
|
+
const [isFloat, setFloat] = useState(false);
|
|
4325
4411
|
useEffect(() => {
|
|
4326
4412
|
setColor(props.value); // Ensures the trigger color updates when props.value changes
|
|
4327
4413
|
}, [props.value]);
|
|
@@ -4340,9 +4426,21 @@ const ColorPickerPopup = (props) => {
|
|
|
4340
4426
|
align: "start",
|
|
4341
4427
|
overflowBoundary: document.body,
|
|
4342
4428
|
autoSize: true,
|
|
4343
|
-
}, open: popoverOpen, trapFocus: true, onOpenChange: (_, data) => setPopoverOpen(data.open), children: [jsx(PopoverTrigger, { disableButtonEnhancement: true, children: jsx(ColorSwatch, { borderColor: tokens.colorNeutralShadowKeyDarker, size: "small", color: color.toHexString(), value: color.toHexString().slice(1) }) }), jsx(PopoverSurface, { children: jsxs("div", { className: classes.
|
|
4344
|
-
|
|
4345
|
-
|
|
4429
|
+
}, open: popoverOpen, trapFocus: true, onOpenChange: (_, data) => setPopoverOpen(data.open), children: [jsx(PopoverTrigger, { disableButtonEnhancement: true, children: jsx(ColorSwatch, { borderColor: tokens.colorNeutralShadowKeyDarker, size: "small", color: color.toHexString(), value: color.toHexString().slice(1) }) }), jsx(PopoverSurface, { children: jsxs("div", { className: classes.container, children: [jsxs(ColorPicker, { className: classes.colorPicker, color: rgbaToHsv(color), onColorChange: handleColorPickerChange, children: [jsx(ColorArea, { inputX: { "aria-label": "Saturation" }, inputY: { "aria-label": "Brightness" } }), jsx(ColorSlider, { "aria-label": "Hue" }), color instanceof Color4 && jsx(AlphaSlider, { "aria-label": "Alpha" })] }), jsxs("div", { className: classes.row, children: [jsx("div", { className: classes.previewColor, style: { backgroundColor: color.toHexString() } }), jsx(NumberDropdown, { className: classes.inputField, infoLabel: {
|
|
4430
|
+
label: "Color Space",
|
|
4431
|
+
info: jsx(Body1, { children: "Today this is not mutable as the color space is determined by the entity. Soon we will allow swapping" }),
|
|
4432
|
+
}, options: [
|
|
4433
|
+
{ label: "Gamma", value: 0 },
|
|
4434
|
+
{ label: "Linear", value: 1 },
|
|
4435
|
+
], disabled: true, value: isLinear ? 1 : 0, onChange: (val) => setIsLinear(val === 1) }), jsx(NumberDropdown, { className: classes.inputField, infoLabel: {
|
|
4436
|
+
label: "Data Type",
|
|
4437
|
+
info: jsx(Body1, { children: "We will introduce this functionality soon!" }),
|
|
4438
|
+
}, options: [
|
|
4439
|
+
{ label: "Int", value: 0 },
|
|
4440
|
+
{ label: "Float", value: 1 },
|
|
4441
|
+
], disabled: true, value: isFloat ? 1 : 0, onChange: (val) => setFloat(val === 1) })] }), jsxs("div", { className: classes.inputRow, children: [jsx(InputRgbField, { title: "Red", value: color, rgbKey: "r", onChange: handleChange }), jsx(InputRgbField, { title: "Green", value: color, rgbKey: "g", onChange: handleChange }), jsx(InputRgbField, { title: "Blue", value: color, rgbKey: "b", onChange: handleChange }), jsx(InputAlphaField, { color: color, onChange: handleChange })] }), jsxs("div", { className: classes.inputRow, children: [jsx(InputHsvField, { title: "Hue", value: color, hsvKey: "h", max: 360, onChange: handleChange }), jsx(InputHsvField, { title: "Saturation", value: color, hsvKey: "s", max: 100, scale: 100, onChange: handleChange }), jsx(InputHsvField, { title: "Value", value: color, hsvKey: "v", max: 100, scale: 100, onChange: handleChange })] }), jsx("div", { className: classes.inputRow, children: jsx(InputHexField, { title: "Hexadecimal", linearHex: isLinear, isLinearMode: isLinear, value: color, onChange: handleChange }) })] }) })] }));
|
|
4442
|
+
};
|
|
4443
|
+
const HEX_REGEX = RegExp(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3}|[A-Fa-f0-9]{8})$/);
|
|
4346
4444
|
/**
|
|
4347
4445
|
* Component which displays the passed in color's HEX value, either in linearSpace (if linearHex is true) or in gamma space
|
|
4348
4446
|
* When the hex color is changed by user, component calculates the new Color3/4 value and calls onChange
|
|
@@ -4352,18 +4450,18 @@ const HEX_REGEX = RegExp(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/);
|
|
|
4352
4450
|
* @returns
|
|
4353
4451
|
*/
|
|
4354
4452
|
const InputHexField = (props) => {
|
|
4355
|
-
const
|
|
4453
|
+
const classes = useColorPickerStyles();
|
|
4356
4454
|
const { title, value, onChange, linearHex, isLinearMode } = props;
|
|
4357
|
-
return (jsx(
|
|
4358
|
-
|
|
4359
|
-
|
|
4360
|
-
|
|
4361
|
-
|
|
4362
|
-
|
|
4363
|
-
|
|
4364
|
-
|
|
4365
|
-
|
|
4366
|
-
|
|
4455
|
+
return (jsx(TextInput, { disabled: linearHex ? !isLinearMode : false, className: classes.inputField, value: linearHex ? value.toLinearSpace().toHexString() : value.toHexString(), validator: (val) => val != "" && HEX_REGEX.test(val), onChange: (val) => (linearHex ? onChange(Color3.FromHexString(val).toGammaSpace()) : onChange(Color3.FromHexString(val))), infoLabel: title
|
|
4456
|
+
? {
|
|
4457
|
+
label: title,
|
|
4458
|
+
// If not representing a linearHex, no info is needed.
|
|
4459
|
+
info: !props.linearHex ? undefined : !isLinearMode ? ( // If representing a linear hex but we are in gammaMode, simple message explaining why linearHex is disabled
|
|
4460
|
+
jsx(Fragment, { children: " This color picker is attached to an entity whose color is stored in gamma space, so we are showing linear hex in disabled view " })) : (
|
|
4461
|
+
// If representing a linear hex and we are in linearMode, give information about how to use these hex values
|
|
4462
|
+
jsxs(Fragment, { children: ["This color picker is attached to an entity whose color is stored in linear space (ex: PBR Material), and Babylon converts the color to gamma space before rendering on screen because the human eye is best at processing colors in gamma space. We thus also want to display the color picker in gamma space so that the color chosen here will match the color seen in your entity.", jsx("br", {}), "If you want to copy/paste the HEX into your code, you can either use", jsx(Body1Strong, { children: "Color3.FromHexString(LINEAR_HEX)" }), jsx("br", {}), "or", jsx("br", {}), jsx(Body1Strong, { children: "Color3.FromHexString(GAMMA_HEX).toLinearSpace()" }), jsx("br", {}), jsx("br", {}), jsx(Link, { href: "https://doc.babylonjs.com/preparingArtForBabylon/controllingColorSpace/", children: " Read more in our docs! " })] })),
|
|
4463
|
+
}
|
|
4464
|
+
: undefined }));
|
|
4367
4465
|
};
|
|
4368
4466
|
const InputRgbField = (props) => {
|
|
4369
4467
|
const { value, onChange, title, rgbKey } = props;
|
|
@@ -4373,7 +4471,7 @@ const InputRgbField = (props) => {
|
|
|
4373
4471
|
newColor[rgbKey] = val / 255.0; // Convert to 0-1 range
|
|
4374
4472
|
onChange(newColor);
|
|
4375
4473
|
}, [value, onChange, rgbKey]);
|
|
4376
|
-
return (jsx(
|
|
4474
|
+
return (jsx(SpinButton, { title: title, infoLabel: title ? { label: title } : undefined, className: classes.inputField, min: 0, max: 255, value: Math.round(value[rgbKey] * 255), forceInt: true, onChange: handleChange }));
|
|
4377
4475
|
};
|
|
4378
4476
|
function rgbaToHsv(color) {
|
|
4379
4477
|
const c = new Color3(color.r, color.g, color.b);
|
|
@@ -4399,7 +4497,7 @@ const InputHsvField = (props) => {
|
|
|
4399
4497
|
}
|
|
4400
4498
|
props.onChange(newColor);
|
|
4401
4499
|
}, [value, onChange, hsvKey, scale]);
|
|
4402
|
-
return (jsx(
|
|
4500
|
+
return (jsx(SpinButton, { infoLabel: title ? { label: title } : undefined, title: title, className: classes.inputField, min: 0, max: max, value: Math.round(rgbaToHsv(value)[hsvKey] * scale), forceInt: true, onChange: handleChange }));
|
|
4403
4501
|
};
|
|
4404
4502
|
/**
|
|
4405
4503
|
* Displays the alpha value of a color, either in the disabled state (if color is Color3) or as a spin button (if color is Color4).
|
|
@@ -4422,10 +4520,10 @@ const InputAlphaField = (props) => {
|
|
|
4422
4520
|
return Color4.FromColor3(color, value);
|
|
4423
4521
|
}
|
|
4424
4522
|
}, [onChange]);
|
|
4425
|
-
return (jsx(
|
|
4426
|
-
|
|
4427
|
-
|
|
4428
|
-
|
|
4523
|
+
return (jsx(SpinButton, { disabled: color instanceof Color3, min: 0, max: 1, className: classes.inputField, value: color instanceof Color3 ? 1 : color.a, step: 0.01, onChange: handleChange, infoLabel: {
|
|
4524
|
+
label: "Alpha",
|
|
4525
|
+
info: color instanceof Color3 ? (jsx(Fragment, { children: "Because this color picker is representing a Color3, we do not permit modifying alpha from the color picker. You can however modify the entity's alpha property directly, either in code via entity.alpha OR via inspector's transparency section." })) : undefined,
|
|
4526
|
+
} }));
|
|
4429
4527
|
};
|
|
4430
4528
|
|
|
4431
4529
|
/**
|
|
@@ -4435,6 +4533,7 @@ const InputAlphaField = (props) => {
|
|
|
4435
4533
|
* @returns Component wrapping a colorPicker component with a property line
|
|
4436
4534
|
*/
|
|
4437
4535
|
const ColorPropertyLine = forwardRef((props, ref) => {
|
|
4536
|
+
ColorPropertyLine.displayName = "ColorPropertyLine";
|
|
4438
4537
|
const [color, setColor] = useState(props.value);
|
|
4439
4538
|
const onSliderChange = (value, key) => {
|
|
4440
4539
|
let newColor;
|
|
@@ -4558,39 +4657,13 @@ const ArcRotateCameraBehaviorsProperties = (props) => {
|
|
|
4558
4657
|
return (jsxs(Fragment, { children: [jsx(BoundProperty, { component: SwitchPropertyLine, label: "Auto Rotation", target: camera, propertyKey: "useAutoRotationBehavior" }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Bouncing", target: camera, propertyKey: "useBouncingBehavior" }), jsx(BoundProperty, { component: SwitchPropertyLine, label: "Framing", target: camera, propertyKey: "useFramingBehavior" })] }));
|
|
4559
4658
|
};
|
|
4560
4659
|
|
|
4561
|
-
const useDropdownStyles = makeStyles({
|
|
4562
|
-
dropdown: { ...UniformWidthStyling, minWidth: CustomTokens.inputWidth },
|
|
4563
|
-
});
|
|
4564
|
-
/**
|
|
4565
|
-
* Renders a fluent UI dropdown component for the options passed in, and an additional 'Not Defined' option if null is set to true
|
|
4566
|
-
* This component can handle both null and undefined values
|
|
4567
|
-
* @param props
|
|
4568
|
-
* @returns dropdown component
|
|
4569
|
-
*/
|
|
4570
|
-
const Dropdown = (props) => {
|
|
4571
|
-
const classes = useDropdownStyles();
|
|
4572
|
-
const { options, value } = props;
|
|
4573
|
-
const [defaultVal, setDefaultVal] = useState(props.value);
|
|
4574
|
-
useEffect(() => {
|
|
4575
|
-
setDefaultVal(value);
|
|
4576
|
-
}, [props.value]);
|
|
4577
|
-
return (jsx(Dropdown$1, { disabled: props.disabled, size: "medium", className: classes.dropdown, onOptionSelect: (evt, data) => {
|
|
4578
|
-
const value = typeof props.value === "number" ? Number(data.optionValue) : data.optionValue;
|
|
4579
|
-
if (value !== undefined) {
|
|
4580
|
-
setDefaultVal(value);
|
|
4581
|
-
props.onChange(value);
|
|
4582
|
-
}
|
|
4583
|
-
}, selectedOptions: [defaultVal.toString()], value: options.find((o) => o.value === defaultVal)?.label, children: options.map((option) => (jsx(Option, { className: classes.dropdown, value: option.value.toString(), disabled: false, children: option.label }, option.label))) }));
|
|
4584
|
-
};
|
|
4585
|
-
const NumberDropdown = Dropdown;
|
|
4586
|
-
const StringDropdown = Dropdown;
|
|
4587
|
-
|
|
4588
4660
|
/**
|
|
4589
4661
|
* Wraps a dropdown in a property line
|
|
4590
4662
|
* @param props - PropertyLineProps and DropdownProps
|
|
4591
4663
|
* @returns property-line wrapped dropdown
|
|
4592
4664
|
*/
|
|
4593
4665
|
const DropdownPropertyLine = forwardRef((props, ref) => {
|
|
4666
|
+
DropdownPropertyLine.displayName = "DropdownPropertyLine";
|
|
4594
4667
|
return (jsx(PropertyLine, { ...props, ref: ref, children: jsx(Dropdown, { ...props }) }));
|
|
4595
4668
|
});
|
|
4596
4669
|
/**
|
|
@@ -5380,6 +5453,7 @@ const useInputStyles = makeStyles({
|
|
|
5380
5453
|
* @returns
|
|
5381
5454
|
*/
|
|
5382
5455
|
const Textarea = (props) => {
|
|
5456
|
+
Textarea.displayName = "Textarea";
|
|
5383
5457
|
const classes = useInputStyles();
|
|
5384
5458
|
const handleChange = (event, _data) => {
|
|
5385
5459
|
event.stopPropagation(); // Prevent event propagation
|
|
@@ -5501,7 +5575,7 @@ function SaveMetadata(entity, metadata) {
|
|
|
5501
5575
|
entity.metadata = metadata;
|
|
5502
5576
|
}
|
|
5503
5577
|
}
|
|
5504
|
-
const useStyles$
|
|
5578
|
+
const useStyles$4 = makeStyles({
|
|
5505
5579
|
buttonDiv: {
|
|
5506
5580
|
display: "grid",
|
|
5507
5581
|
gridAutoFlow: "column",
|
|
@@ -5516,7 +5590,7 @@ const useStyles$3 = makeStyles({
|
|
|
5516
5590
|
*/
|
|
5517
5591
|
const MetadataProperties = (props) => {
|
|
5518
5592
|
const { entity } = props;
|
|
5519
|
-
const classes = useStyles$
|
|
5593
|
+
const classes = useStyles$4();
|
|
5520
5594
|
const metadata = useProperty(entity, "metadata");
|
|
5521
5595
|
const stringifiedMetadata = useMemo(() => StringifyMetadata(metadata) ?? "", [metadata]);
|
|
5522
5596
|
const metadataType = useMemo(() => GetMetadataEntityType(metadata), [metadata]);
|
|
@@ -5990,6 +6064,7 @@ const useGradientStyles = makeStyles({
|
|
|
5990
6064
|
* @returns A React component
|
|
5991
6065
|
*/
|
|
5992
6066
|
const Gradient = (props) => {
|
|
6067
|
+
Gradient.displayName = "Gradient";
|
|
5993
6068
|
const [gradient, setGradient] = useState(props.value);
|
|
5994
6069
|
const classes = useGradientStyles();
|
|
5995
6070
|
useEffect(() => {
|
|
@@ -6046,6 +6121,7 @@ function GradientsToListItems(gradients) {
|
|
|
6046
6121
|
})) ?? []);
|
|
6047
6122
|
}
|
|
6048
6123
|
const FactorGradientList = (props) => {
|
|
6124
|
+
FactorGradientList.displayName = "FactorGradientList";
|
|
6049
6125
|
const { gradients } = props;
|
|
6050
6126
|
const items = GradientsToListItems(gradients);
|
|
6051
6127
|
return (jsx(List, { addButtonLabel: items.length > 0 ? `Add new ${props.label}` : `Use ${props.label}s`, items: items, onDelete: (item) => props.removeGradient(item.data), onAdd: () => {
|
|
@@ -6065,6 +6141,7 @@ const FactorGradientList = (props) => {
|
|
|
6065
6141
|
} }, "Factor"));
|
|
6066
6142
|
};
|
|
6067
6143
|
const Color3GradientList = (props) => {
|
|
6144
|
+
Color3GradientList.displayName = "Color3GradientList";
|
|
6068
6145
|
const { gradients } = props;
|
|
6069
6146
|
const items = GradientsToListItems(gradients);
|
|
6070
6147
|
return (jsx(List, { addButtonLabel: items.length > 0 ? `Add new ${props.label}` : `Use ${props.label}s`, items: items, onDelete: (item) => props.removeGradient(item.data), onAdd: () => {
|
|
@@ -6083,6 +6160,7 @@ const Color3GradientList = (props) => {
|
|
|
6083
6160
|
} }, "Color3"));
|
|
6084
6161
|
};
|
|
6085
6162
|
const Color4GradientList = (props) => {
|
|
6163
|
+
Color4GradientList.displayName = "Color4GradientList";
|
|
6086
6164
|
const { gradients } = props;
|
|
6087
6165
|
const items = GradientsToListItems(gradients);
|
|
6088
6166
|
return (jsx(List, { addButtonLabel: items.length > 0 ? `Add new ${props.label}` : `Use ${props.label}s`, items: items, onDelete: (item) => props.removeGradient(item.data), onAdd: () => {
|
|
@@ -6377,6 +6455,7 @@ const PhysicsPropertiesServiceDefinition = {
|
|
|
6377
6455
|
* @returns Checkbox component
|
|
6378
6456
|
*/
|
|
6379
6457
|
const Checkbox = (props) => {
|
|
6458
|
+
Checkbox.displayName = "Checkbox";
|
|
6380
6459
|
const [checked, setChecked] = useState(() => props.value ?? false);
|
|
6381
6460
|
useEffect(() => {
|
|
6382
6461
|
if (props.value != undefined) {
|
|
@@ -6396,6 +6475,7 @@ const Checkbox = (props) => {
|
|
|
6396
6475
|
* @returns property-line wrapped checkbox
|
|
6397
6476
|
*/
|
|
6398
6477
|
const CheckboxPropertyLine = (props) => {
|
|
6478
|
+
CheckboxPropertyLine.displayName = "CheckboxPropertyLine";
|
|
6399
6479
|
return (jsx(PropertyLine, { ...props, children: jsx(Checkbox, { ...props }) }));
|
|
6400
6480
|
};
|
|
6401
6481
|
|
|
@@ -6885,6 +6965,180 @@ function FindTextureType(type) {
|
|
|
6885
6965
|
return null;
|
|
6886
6966
|
}
|
|
6887
6967
|
|
|
6968
|
+
const useStyles$3 = makeStyles({
|
|
6969
|
+
root: { display: "flex", flexDirection: "column", gap: "8px" },
|
|
6970
|
+
controls: {
|
|
6971
|
+
display: "flex",
|
|
6972
|
+
gap: "2px",
|
|
6973
|
+
padding: "2px",
|
|
6974
|
+
width: "100%",
|
|
6975
|
+
justifyContent: "center",
|
|
6976
|
+
},
|
|
6977
|
+
controlButton: {
|
|
6978
|
+
minWidth: "auto",
|
|
6979
|
+
flex: "1 1 0", // Equal flex grow/shrink with 0 basis
|
|
6980
|
+
paddingVertical: "4px",
|
|
6981
|
+
paddingHorizontal: "8px",
|
|
6982
|
+
overflow: "hidden",
|
|
6983
|
+
textOverflow: "ellipsis",
|
|
6984
|
+
},
|
|
6985
|
+
preview: {
|
|
6986
|
+
border: "1px solid #ccc",
|
|
6987
|
+
marginTop: "8px",
|
|
6988
|
+
maxWidth: "100%",
|
|
6989
|
+
marginLeft: "auto",
|
|
6990
|
+
marginRight: "auto",
|
|
6991
|
+
display: "block",
|
|
6992
|
+
},
|
|
6993
|
+
});
|
|
6994
|
+
// This method of holding TextureChannels was brought over from inspectorv1 and can likely be refactored/simplified
|
|
6995
|
+
const TextureChannelStates = {
|
|
6996
|
+
R: { R: true, G: false, B: false, A: false },
|
|
6997
|
+
G: { R: false, G: true, B: false, A: false },
|
|
6998
|
+
B: { R: false, G: false, B: true, A: false },
|
|
6999
|
+
A: { R: false, G: false, B: false, A: true },
|
|
7000
|
+
ALL: { R: true, G: true, B: true, A: true },
|
|
7001
|
+
};
|
|
7002
|
+
const TexturePreview = (props) => {
|
|
7003
|
+
const { texture, width, height } = props;
|
|
7004
|
+
const classes = useStyles$3();
|
|
7005
|
+
const canvasRef = useRef(null);
|
|
7006
|
+
const [channels, setChannels] = useState(TextureChannelStates.ALL);
|
|
7007
|
+
const [face, setFace] = useState(0);
|
|
7008
|
+
const internalTexture = useProperty(texture, "_texture");
|
|
7009
|
+
const updatePreviewCanvasSize = useCallback((previewCanvas) => {
|
|
7010
|
+
// This logic was brought over from inspectorv1 and can likely be refactored/simplified
|
|
7011
|
+
const size = texture.getSize();
|
|
7012
|
+
const ratio = size.width / size.height;
|
|
7013
|
+
let w = width;
|
|
7014
|
+
let h = (w / ratio) | 1;
|
|
7015
|
+
const engine = texture.getScene()?.getEngine();
|
|
7016
|
+
if (engine && h > engine.getCaps().maxTextureSize) {
|
|
7017
|
+
w = size.width;
|
|
7018
|
+
h = size.height;
|
|
7019
|
+
}
|
|
7020
|
+
previewCanvas.width = w;
|
|
7021
|
+
previewCanvas.height = h;
|
|
7022
|
+
previewCanvas.style.width = w + "px";
|
|
7023
|
+
previewCanvas.style.height = h + "px";
|
|
7024
|
+
return {
|
|
7025
|
+
w: w,
|
|
7026
|
+
h: h,
|
|
7027
|
+
};
|
|
7028
|
+
}, [canvasRef.current, texture, width, height, internalTexture]);
|
|
7029
|
+
const updatePreviewAsync = useCallback(async () => {
|
|
7030
|
+
const previewCanvas = canvasRef.current;
|
|
7031
|
+
if (!previewCanvas) {
|
|
7032
|
+
return;
|
|
7033
|
+
}
|
|
7034
|
+
try {
|
|
7035
|
+
await WhenTextureReadyAsync(texture); // Ensure texture is loaded before grabbing size
|
|
7036
|
+
const { w, h } = updatePreviewCanvasSize(previewCanvas); // Grab desired size
|
|
7037
|
+
const data = await ApplyChannelsToTextureDataAsync(texture, w, h, face, channels); // get channel data to load onto canvas context
|
|
7038
|
+
const context = previewCanvas.getContext("2d");
|
|
7039
|
+
if (context) {
|
|
7040
|
+
const imageData = context.createImageData(w, h);
|
|
7041
|
+
imageData.data.set(data);
|
|
7042
|
+
context.putImageData(imageData, 0, 0);
|
|
7043
|
+
}
|
|
7044
|
+
}
|
|
7045
|
+
catch {
|
|
7046
|
+
updatePreviewCanvasSize(previewCanvas); // If we fail above, best effort sizing preview canvas
|
|
7047
|
+
}
|
|
7048
|
+
}, [[texture, width, height, face, channels, internalTexture]]);
|
|
7049
|
+
useEffect(() => {
|
|
7050
|
+
void updatePreviewAsync();
|
|
7051
|
+
}, [texture, width, height, face, channels, internalTexture]);
|
|
7052
|
+
return (jsxs("div", { className: classes.root, children: [texture.isCube ? (jsx(Toolbar$1, { className: classes.controls, "aria-label": "Cube Faces", children: ["+X", "-X", "+Y", "-Y", "+Z", "-Z"].map((label, idx) => (jsx(ToolbarButton, { className: classes.controlButton, appearance: face === idx ? "primary" : "subtle", onClick: () => setFace(idx), children: label }, label))) })) : (jsx(Toolbar$1, { className: classes.controls, "aria-label": "Channels", children: ["R", "G", "B", "A", "ALL"].map((ch) => (jsx(ToolbarButton, { className: classes.controlButton, appearance: channels === TextureChannelStates[ch] ? "primary" : "subtle", onClick: () => setChannels(TextureChannelStates[ch]), children: ch }, ch))) })), jsx("canvas", { ref: canvasRef, className: classes.preview }), texture.isRenderTarget && (jsx(Button$1, { appearance: "outline", onClick: () => {
|
|
7053
|
+
void updatePreviewAsync();
|
|
7054
|
+
}, children: "Refresh" }))] }));
|
|
7055
|
+
};
|
|
7056
|
+
/**
|
|
7057
|
+
* Gets the data of the specified texture by rendering it to an intermediate RGBA texture and retrieving the bytes from it.
|
|
7058
|
+
* This is convienent to get 8-bit RGBA values for a texture in a GPU compressed format.
|
|
7059
|
+
* @param texture the source texture
|
|
7060
|
+
* @param width the width of the result, which does not have to match the source texture width
|
|
7061
|
+
* @param height the height of the result, which does not have to match the source texture height
|
|
7062
|
+
* @param face if the texture has multiple faces, the face index to use for the source
|
|
7063
|
+
* @param channels a filter for which of the RGBA channels to return in the result
|
|
7064
|
+
* @param lod if the texture has multiple LODs, the lod index to use for the source
|
|
7065
|
+
* @returns the 8-bit texture data
|
|
7066
|
+
*/
|
|
7067
|
+
async function ApplyChannelsToTextureDataAsync(texture, width, height, face, channels, lod = 0) {
|
|
7068
|
+
const data = await GetTextureDataAsync(texture, width, height, face, lod);
|
|
7069
|
+
if (!channels.R || !channels.G || !channels.B || !channels.A) {
|
|
7070
|
+
for (let i = 0; i < width * height * 4; i += 4) {
|
|
7071
|
+
// If alpha is the only channel, just display alpha across all channels
|
|
7072
|
+
if (channels.A && !channels.R && !channels.G && !channels.B) {
|
|
7073
|
+
data[i] = data[i + 3];
|
|
7074
|
+
data[i + 1] = data[i + 3];
|
|
7075
|
+
data[i + 2] = data[i + 3];
|
|
7076
|
+
data[i + 3] = 255;
|
|
7077
|
+
continue;
|
|
7078
|
+
}
|
|
7079
|
+
let r = data[i], g = data[i + 1], b = data[i + 2], a = data[i + 3];
|
|
7080
|
+
// If alpha is not visible, make everything 100% alpha
|
|
7081
|
+
if (!channels.A) {
|
|
7082
|
+
a = 255;
|
|
7083
|
+
}
|
|
7084
|
+
// If only one color channel is selected, map both colors to it. If two are selected, the unused one gets set to 0
|
|
7085
|
+
if (!channels.R) {
|
|
7086
|
+
if (channels.G && !channels.B) {
|
|
7087
|
+
r = g;
|
|
7088
|
+
}
|
|
7089
|
+
else if (channels.B && !channels.G) {
|
|
7090
|
+
r = b;
|
|
7091
|
+
}
|
|
7092
|
+
else {
|
|
7093
|
+
r = 0;
|
|
7094
|
+
}
|
|
7095
|
+
}
|
|
7096
|
+
if (!channels.G) {
|
|
7097
|
+
if (channels.R && !channels.B) {
|
|
7098
|
+
g = r;
|
|
7099
|
+
}
|
|
7100
|
+
else if (channels.B && !channels.R) {
|
|
7101
|
+
g = b;
|
|
7102
|
+
}
|
|
7103
|
+
else {
|
|
7104
|
+
g = 0;
|
|
7105
|
+
}
|
|
7106
|
+
}
|
|
7107
|
+
if (!channels.B) {
|
|
7108
|
+
if (channels.R && !channels.G) {
|
|
7109
|
+
b = r;
|
|
7110
|
+
}
|
|
7111
|
+
else if (channels.G && !channels.R) {
|
|
7112
|
+
b = g;
|
|
7113
|
+
}
|
|
7114
|
+
else {
|
|
7115
|
+
b = 0;
|
|
7116
|
+
}
|
|
7117
|
+
}
|
|
7118
|
+
data[i] = r;
|
|
7119
|
+
data[i + 1] = g;
|
|
7120
|
+
data[i + 2] = b;
|
|
7121
|
+
data[i + 3] = a;
|
|
7122
|
+
}
|
|
7123
|
+
}
|
|
7124
|
+
//To flip image on Y axis.
|
|
7125
|
+
if (texture.invertY || texture.isCube) {
|
|
7126
|
+
const numberOfChannelsByLine = width * 4;
|
|
7127
|
+
const halfHeight = height / 2;
|
|
7128
|
+
for (let i = 0; i < halfHeight; i++) {
|
|
7129
|
+
for (let j = 0; j < numberOfChannelsByLine; j++) {
|
|
7130
|
+
const currentCell = j + i * numberOfChannelsByLine;
|
|
7131
|
+
const targetLine = height - i - 1;
|
|
7132
|
+
const targetCell = j + targetLine * numberOfChannelsByLine;
|
|
7133
|
+
const temp = data[currentCell];
|
|
7134
|
+
data[currentCell] = data[targetCell];
|
|
7135
|
+
data[targetCell] = temp;
|
|
7136
|
+
}
|
|
7137
|
+
}
|
|
7138
|
+
}
|
|
7139
|
+
return data;
|
|
7140
|
+
}
|
|
7141
|
+
|
|
6888
7142
|
const BaseTexturePreviewProperties = (props) => {
|
|
6889
7143
|
const { texture } = props;
|
|
6890
7144
|
const isUpdatable = texture instanceof Texture || texture instanceof CubeTexture;
|
|
@@ -6911,11 +7165,11 @@ const BaseTexturePreviewProperties = (props) => {
|
|
|
6911
7165
|
};
|
|
6912
7166
|
}, undefined, true);
|
|
6913
7167
|
}, [texture]);
|
|
6914
|
-
return (jsxs(Fragment, { children: [jsx(
|
|
7168
|
+
return (jsxs(Fragment, { children: [jsx(TexturePreview, { texture: texture, width: 256, height: 256 }), isUpdatable && (jsx(FileUploadLine, { label: "Load Texture From File", accept: ".jpg, .png, .tga, .dds, .env, .exr", onClick: (files) => {
|
|
6915
7169
|
if (files.length > 0) {
|
|
6916
7170
|
updateTexture(files[0]);
|
|
6917
7171
|
}
|
|
6918
|
-
} })), jsx(
|
|
7172
|
+
} })), jsx(ButtonLine, { label: "Edit Texture (coming soon!)", onClick: () => { } })] }));
|
|
6919
7173
|
};
|
|
6920
7174
|
const BaseTextureGeneralProperties = (props) => {
|
|
6921
7175
|
const { texture } = props;
|
|
@@ -8273,6 +8527,7 @@ const useStyles$2 = makeStyles({
|
|
|
8273
8527
|
* @returns
|
|
8274
8528
|
*/
|
|
8275
8529
|
const ComboBox = (props) => {
|
|
8530
|
+
ComboBox.displayName = "ComboBox";
|
|
8276
8531
|
const comboId = useId();
|
|
8277
8532
|
const styles = useStyles$2();
|
|
8278
8533
|
const [query, setQuery] = useState("");
|
|
@@ -8333,6 +8588,7 @@ const useDraggableStyles = makeStyles({
|
|
|
8333
8588
|
},
|
|
8334
8589
|
});
|
|
8335
8590
|
const DraggableLine = (props) => {
|
|
8591
|
+
DraggableLine.displayName = "DraggableLine";
|
|
8336
8592
|
const classes = useDraggableStyles();
|
|
8337
8593
|
return (jsxs("div", { className: classes.draggable, title: props.tooltip, draggable: true, onDragStart: (event) => {
|
|
8338
8594
|
event.dataTransfer.setData(props.format, props.data);
|
|
@@ -8345,6 +8601,7 @@ const DraggableLine = (props) => {
|
|
|
8345
8601
|
* @returns The positioned popover component
|
|
8346
8602
|
*/
|
|
8347
8603
|
const PositionedPopover = (props) => {
|
|
8604
|
+
PositionedPopover.displayName = "PositionedPopover";
|
|
8348
8605
|
const [open, setOpen] = useState(false);
|
|
8349
8606
|
useEffect(() => {
|
|
8350
8607
|
setOpen(props.visible);
|
|
@@ -8373,6 +8630,7 @@ const useStyles$1 = makeStyles({
|
|
|
8373
8630
|
},
|
|
8374
8631
|
});
|
|
8375
8632
|
const SearchBar = forwardRef((props, ref) => {
|
|
8633
|
+
SearchBar.displayName = "SearchBar";
|
|
8376
8634
|
const classes = useStyles$1();
|
|
8377
8635
|
const onChange = (_, data) => {
|
|
8378
8636
|
props.onChange(data.value);
|
|
@@ -8442,6 +8700,7 @@ const useSearchBoxStyles = makeStyles({
|
|
|
8442
8700
|
* @returns The search box component
|
|
8443
8701
|
*/
|
|
8444
8702
|
const SearchBox = (props) => {
|
|
8703
|
+
SearchBox.displayName = "SearchBox";
|
|
8445
8704
|
const classes = useSearchBoxStyles();
|
|
8446
8705
|
const [selectedIndex, setSelectedIndex] = useState(0);
|
|
8447
8706
|
const [items, setItems] = useState(props.items);
|
|
@@ -8503,10 +8762,14 @@ const Pane = (props) => {
|
|
|
8503
8762
|
* @returns property-line wrapped input hex component
|
|
8504
8763
|
*/
|
|
8505
8764
|
const HexPropertyLine = (props) => {
|
|
8765
|
+
HexPropertyLine.displayName = "HexPropertyLine";
|
|
8506
8766
|
return (jsx(PropertyLine, { ...props, children: jsx(InputHexField, { ...props }) }));
|
|
8507
8767
|
};
|
|
8508
8768
|
|
|
8509
|
-
const SpinButtonPropertyLine = (props) =>
|
|
8769
|
+
const SpinButtonPropertyLine = (props) => {
|
|
8770
|
+
SpinButtonPropertyLine.displayName = "SpinButtonPropertyLine";
|
|
8771
|
+
return (jsx(PropertyLine, { ...props, children: jsx(SpinButton, { ...props }) }));
|
|
8772
|
+
};
|
|
8510
8773
|
|
|
8511
8774
|
/**
|
|
8512
8775
|
* Wraps textarea in a property line
|
|
@@ -8514,6 +8777,7 @@ const SpinButtonPropertyLine = (props) => (jsx(PropertyLine, { ...props, childre
|
|
|
8514
8777
|
* @returns property-line wrapped text
|
|
8515
8778
|
*/
|
|
8516
8779
|
const TextAreaPropertyLine = (props) => {
|
|
8780
|
+
TextAreaPropertyLine.displayName = "TextAreaPropertyLine";
|
|
8517
8781
|
return (jsx(PropertyLine, { ...props, children: jsx(Textarea, { ...props }) }));
|
|
8518
8782
|
};
|
|
8519
8783
|
|