@itwin/map-layers 3.0.0-dev.76 → 3.0.0-dev.80
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/{map-layers.d.ts → cjs/map-layers.d.ts} +0 -0
- package/lib/cjs/map-layers.d.ts.map +1 -0
- package/lib/{map-layers.js → cjs/map-layers.js} +0 -0
- package/lib/cjs/map-layers.js.map +1 -0
- package/lib/{mapLayers.d.ts → cjs/mapLayers.d.ts} +0 -0
- package/lib/cjs/mapLayers.d.ts.map +1 -0
- package/lib/{mapLayers.js → cjs/mapLayers.js} +0 -0
- package/lib/cjs/mapLayers.js.map +1 -0
- package/lib/{public → cjs/public}/locales/en/mapLayers.json +5 -5
- package/lib/{ui → cjs/ui}/Interfaces.d.ts +0 -0
- package/lib/cjs/ui/Interfaces.d.ts.map +1 -0
- package/lib/{ui → cjs/ui}/Interfaces.js +0 -0
- package/lib/cjs/ui/Interfaces.js.map +1 -0
- package/lib/{ui → cjs/ui}/MapLayersUiItemsProvider.d.ts +0 -0
- package/lib/cjs/ui/MapLayersUiItemsProvider.d.ts.map +1 -0
- package/lib/{ui → cjs/ui}/MapLayersUiItemsProvider.js +0 -0
- package/lib/cjs/ui/MapLayersUiItemsProvider.js.map +1 -0
- package/lib/{ui → cjs/ui}/widget/AttachLayerPopupButton.d.ts +0 -0
- package/lib/cjs/ui/widget/AttachLayerPopupButton.d.ts.map +1 -0
- package/lib/{ui → cjs/ui}/widget/AttachLayerPopupButton.js +0 -0
- package/lib/cjs/ui/widget/AttachLayerPopupButton.js.map +1 -0
- package/lib/{ui → cjs/ui}/widget/BasemapPanel.d.ts +0 -0
- package/lib/cjs/ui/widget/BasemapPanel.d.ts.map +1 -0
- package/lib/{ui → cjs/ui}/widget/BasemapPanel.js +0 -0
- package/lib/cjs/ui/widget/BasemapPanel.js.map +1 -0
- package/lib/{ui → cjs/ui}/widget/BasemapPanel.scss +1 -1
- package/lib/{ui → cjs/ui}/widget/ConfirmMessageDialog.d.ts +0 -0
- package/lib/cjs/ui/widget/ConfirmMessageDialog.d.ts.map +1 -0
- package/lib/{ui → cjs/ui}/widget/ConfirmMessageDialog.js +0 -0
- package/lib/cjs/ui/widget/ConfirmMessageDialog.js.map +1 -0
- package/lib/{ui → cjs/ui}/widget/MapLayerDroppable.d.ts +0 -0
- package/lib/cjs/ui/widget/MapLayerDroppable.d.ts.map +1 -0
- package/lib/{ui → cjs/ui}/widget/MapLayerDroppable.js +0 -0
- package/lib/cjs/ui/widget/MapLayerDroppable.js.map +1 -0
- package/lib/{ui → cjs/ui}/widget/MapLayerManager.d.ts +0 -0
- package/lib/cjs/ui/widget/MapLayerManager.d.ts.map +1 -0
- package/lib/{ui → cjs/ui}/widget/MapLayerManager.js +1 -1
- package/lib/cjs/ui/widget/MapLayerManager.js.map +1 -0
- package/lib/{ui → cjs/ui}/widget/MapLayerManager.scss +1 -1
- package/lib/{ui → cjs/ui}/widget/MapLayerSettingsMenu.d.ts +0 -0
- package/lib/cjs/ui/widget/MapLayerSettingsMenu.d.ts.map +1 -0
- package/lib/{ui → cjs/ui}/widget/MapLayerSettingsMenu.js +0 -0
- package/lib/cjs/ui/widget/MapLayerSettingsMenu.js.map +1 -0
- package/lib/{ui → cjs/ui}/widget/MapLayerSettingsPopupButton.d.ts +0 -0
- package/lib/cjs/ui/widget/MapLayerSettingsPopupButton.d.ts.map +1 -0
- package/lib/{ui → cjs/ui}/widget/MapLayerSettingsPopupButton.js +0 -0
- package/lib/cjs/ui/widget/MapLayerSettingsPopupButton.js.map +1 -0
- package/lib/{ui → cjs/ui}/widget/MapLayerSettingsPopupButton.scss +1 -1
- package/lib/{ui → cjs/ui}/widget/MapLayersWidget.d.ts +0 -0
- package/lib/cjs/ui/widget/MapLayersWidget.d.ts.map +1 -0
- package/lib/{ui → cjs/ui}/widget/MapLayersWidget.js +0 -0
- package/lib/cjs/ui/widget/MapLayersWidget.js.map +1 -0
- package/lib/{ui → cjs/ui}/widget/MapManagerSettings.d.ts +0 -0
- package/lib/cjs/ui/widget/MapManagerSettings.d.ts.map +1 -0
- package/lib/{ui → cjs/ui}/widget/MapManagerSettings.js +0 -0
- package/lib/cjs/ui/widget/MapManagerSettings.js.map +1 -0
- package/lib/{ui → cjs/ui}/widget/MapManagerSettings.scss +1 -1
- package/lib/{ui → cjs/ui}/widget/MapUrlDialog.d.ts +0 -0
- package/lib/cjs/ui/widget/MapUrlDialog.d.ts.map +1 -0
- package/lib/{ui → cjs/ui}/widget/MapUrlDialog.js +3 -3
- package/lib/cjs/ui/widget/MapUrlDialog.js.map +1 -0
- package/lib/{ui → cjs/ui}/widget/MapUrlDialog.scss +1 -1
- package/lib/{ui → cjs/ui}/widget/SubLayersDataProvider.d.ts +0 -0
- package/lib/cjs/ui/widget/SubLayersDataProvider.d.ts.map +1 -0
- package/lib/{ui → cjs/ui}/widget/SubLayersDataProvider.js +0 -0
- package/lib/cjs/ui/widget/SubLayersDataProvider.js.map +1 -0
- package/lib/{ui → cjs/ui}/widget/SubLayersPopupButton.d.ts +0 -0
- package/lib/cjs/ui/widget/SubLayersPopupButton.d.ts.map +1 -0
- package/lib/{ui → cjs/ui}/widget/SubLayersPopupButton.js +0 -0
- package/lib/cjs/ui/widget/SubLayersPopupButton.js.map +1 -0
- package/lib/{ui → cjs/ui}/widget/SubLayersTree.d.ts +0 -0
- package/lib/cjs/ui/widget/SubLayersTree.d.ts.map +1 -0
- package/lib/{ui → cjs/ui}/widget/SubLayersTree.js +0 -0
- package/lib/cjs/ui/widget/SubLayersTree.js.map +1 -0
- package/lib/{ui → cjs/ui}/widget/SubLayersTree.scss +1 -1
- package/lib/{ui → cjs/ui}/widget/TransparencyPopupButton.d.ts +0 -0
- package/lib/cjs/ui/widget/TransparencyPopupButton.d.ts.map +1 -0
- package/lib/{ui → cjs/ui}/widget/TransparencyPopupButton.js +0 -0
- package/lib/cjs/ui/widget/TransparencyPopupButton.js.map +1 -0
- package/lib/{ui → cjs/ui}/widget/TransparencyPopupButton.scss +1 -1
- package/lib/esm/map-layers.d.ts +5 -0
- package/lib/esm/map-layers.d.ts.map +1 -0
- package/lib/esm/map-layers.js +9 -0
- package/lib/esm/map-layers.js.map +1 -0
- package/lib/esm/mapLayers.d.ts +29 -0
- package/lib/esm/mapLayers.d.ts.map +1 -0
- package/lib/esm/mapLayers.js +50 -0
- package/lib/esm/mapLayers.js.map +1 -0
- package/lib/esm/public/locales/en/mapLayers.json +113 -0
- package/lib/esm/ui/Interfaces.d.ts +32 -0
- package/lib/esm/ui/Interfaces.d.ts.map +1 -0
- package/lib/esm/ui/Interfaces.js +2 -0
- package/lib/esm/ui/Interfaces.js.map +1 -0
- package/lib/esm/ui/MapLayersUiItemsProvider.d.ts +23 -0
- package/lib/esm/ui/MapLayersUiItemsProvider.d.ts.map +1 -0
- package/lib/esm/ui/MapLayersUiItemsProvider.js +50 -0
- package/lib/esm/ui/MapLayersUiItemsProvider.js.map +1 -0
- package/lib/esm/ui/widget/AttachLayerPopupButton.d.ts +14 -0
- package/lib/esm/ui/widget/AttachLayerPopupButton.d.ts.map +1 -0
- package/lib/esm/ui/widget/AttachLayerPopupButton.js +308 -0
- package/lib/esm/ui/widget/AttachLayerPopupButton.js.map +1 -0
- package/lib/esm/ui/widget/BasemapPanel.d.ts +5 -0
- package/lib/esm/ui/widget/BasemapPanel.d.ts.map +1 -0
- package/lib/esm/ui/widget/BasemapPanel.js +141 -0
- package/lib/esm/ui/widget/BasemapPanel.js.map +1 -0
- package/lib/esm/ui/widget/BasemapPanel.scss +98 -0
- package/lib/esm/ui/widget/ConfirmMessageDialog.d.ts +22 -0
- package/lib/esm/ui/widget/ConfirmMessageDialog.d.ts.map +1 -0
- package/lib/esm/ui/widget/ConfirmMessageDialog.js +22 -0
- package/lib/esm/ui/widget/ConfirmMessageDialog.js.map +1 -0
- package/lib/esm/ui/widget/MapLayerDroppable.d.ts +19 -0
- package/lib/esm/ui/widget/MapLayerDroppable.d.ts.map +1 -0
- package/lib/esm/ui/widget/MapLayerDroppable.js +80 -0
- package/lib/esm/ui/widget/MapLayerDroppable.js.map +1 -0
- package/lib/esm/ui/widget/MapLayerManager.d.ts +27 -0
- package/lib/esm/ui/widget/MapLayerManager.d.ts.map +1 -0
- package/lib/esm/ui/widget/MapLayerManager.js +347 -0
- package/lib/esm/ui/widget/MapLayerManager.js.map +1 -0
- package/lib/esm/ui/widget/MapLayerManager.scss +525 -0
- package/lib/esm/ui/widget/MapLayerSettingsMenu.d.ts +10 -0
- package/lib/esm/ui/widget/MapLayerSettingsMenu.d.ts.map +1 -0
- package/lib/esm/ui/widget/MapLayerSettingsMenu.js +79 -0
- package/lib/esm/ui/widget/MapLayerSettingsMenu.js.map +1 -0
- package/lib/esm/ui/widget/MapLayerSettingsPopupButton.d.ts +5 -0
- package/lib/esm/ui/widget/MapLayerSettingsPopupButton.d.ts.map +1 -0
- package/lib/esm/ui/widget/MapLayerSettingsPopupButton.js +31 -0
- package/lib/esm/ui/widget/MapLayerSettingsPopupButton.js.map +1 -0
- package/lib/esm/ui/widget/MapLayerSettingsPopupButton.scss +31 -0
- package/lib/esm/ui/widget/MapLayersWidget.d.ts +12 -0
- package/lib/esm/ui/widget/MapLayersWidget.d.ts.map +1 -0
- package/lib/esm/ui/widget/MapLayersWidget.js +23 -0
- package/lib/esm/ui/widget/MapLayersWidget.js.map +1 -0
- package/lib/esm/ui/widget/MapManagerSettings.d.ts +4 -0
- package/lib/esm/ui/widget/MapManagerSettings.d.ts.map +1 -0
- package/lib/esm/ui/widget/MapManagerSettings.js +168 -0
- package/lib/esm/ui/widget/MapManagerSettings.js.map +1 -0
- package/lib/esm/ui/widget/MapManagerSettings.scss +23 -0
- package/lib/esm/ui/widget/MapUrlDialog.d.ts +23 -0
- package/lib/esm/ui/widget/MapUrlDialog.d.ts.map +1 -0
- package/lib/esm/ui/widget/MapUrlDialog.js +346 -0
- package/lib/esm/ui/widget/MapUrlDialog.js.map +1 -0
- package/lib/esm/ui/widget/MapUrlDialog.scss +85 -0
- package/lib/esm/ui/widget/SubLayersDataProvider.d.ts +21 -0
- package/lib/esm/ui/widget/SubLayersDataProvider.d.ts.map +1 -0
- package/lib/esm/ui/widget/SubLayersDataProvider.js +73 -0
- package/lib/esm/ui/widget/SubLayersDataProvider.js.map +1 -0
- package/lib/esm/ui/widget/SubLayersPopupButton.d.ts +11 -0
- package/lib/esm/ui/widget/SubLayersPopupButton.d.ts.map +1 -0
- package/lib/esm/ui/widget/SubLayersPopupButton.js +36 -0
- package/lib/esm/ui/widget/SubLayersPopupButton.js.map +1 -0
- package/lib/esm/ui/widget/SubLayersTree.d.ts +16 -0
- package/lib/esm/ui/widget/SubLayersTree.d.ts.map +1 -0
- package/lib/esm/ui/widget/SubLayersTree.js +374 -0
- package/lib/esm/ui/widget/SubLayersTree.js.map +1 -0
- package/lib/esm/ui/widget/SubLayersTree.scss +64 -0
- package/lib/esm/ui/widget/TransparencyPopupButton.d.ts +14 -0
- package/lib/esm/ui/widget/TransparencyPopupButton.d.ts.map +1 -0
- package/lib/esm/ui/widget/TransparencyPopupButton.js +44 -0
- package/lib/esm/ui/widget/TransparencyPopupButton.js.map +1 -0
- package/lib/esm/ui/widget/TransparencyPopupButton.scss +53 -0
- package/lib/public/en/mapLayers.json +113 -0
- package/package.json +45 -39
- package/lib/map-layers.d.ts.map +0 -1
- package/lib/map-layers.js.map +0 -1
- package/lib/mapLayers.d.ts.map +0 -1
- package/lib/mapLayers.js.map +0 -1
- package/lib/ui/Interfaces.d.ts.map +0 -1
- package/lib/ui/Interfaces.js.map +0 -1
- package/lib/ui/MapLayersUiItemsProvider.d.ts.map +0 -1
- package/lib/ui/MapLayersUiItemsProvider.js.map +0 -1
- package/lib/ui/widget/AttachLayerPopupButton.d.ts.map +0 -1
- package/lib/ui/widget/AttachLayerPopupButton.js.map +0 -1
- package/lib/ui/widget/BasemapPanel.d.ts.map +0 -1
- package/lib/ui/widget/BasemapPanel.js.map +0 -1
- package/lib/ui/widget/ConfirmMessageDialog.d.ts.map +0 -1
- package/lib/ui/widget/ConfirmMessageDialog.js.map +0 -1
- package/lib/ui/widget/MapLayerDroppable.d.ts.map +0 -1
- package/lib/ui/widget/MapLayerDroppable.js.map +0 -1
- package/lib/ui/widget/MapLayerManager.d.ts.map +0 -1
- package/lib/ui/widget/MapLayerManager.js.map +0 -1
- package/lib/ui/widget/MapLayerSettingsMenu.d.ts.map +0 -1
- package/lib/ui/widget/MapLayerSettingsMenu.js.map +0 -1
- package/lib/ui/widget/MapLayerSettingsPopupButton.d.ts.map +0 -1
- package/lib/ui/widget/MapLayerSettingsPopupButton.js.map +0 -1
- package/lib/ui/widget/MapLayersWidget.d.ts.map +0 -1
- package/lib/ui/widget/MapLayersWidget.js.map +0 -1
- package/lib/ui/widget/MapManagerSettings.d.ts.map +0 -1
- package/lib/ui/widget/MapManagerSettings.js.map +0 -1
- package/lib/ui/widget/MapUrlDialog.d.ts.map +0 -1
- package/lib/ui/widget/MapUrlDialog.js.map +0 -1
- package/lib/ui/widget/SubLayersDataProvider.d.ts.map +0 -1
- package/lib/ui/widget/SubLayersDataProvider.js.map +0 -1
- package/lib/ui/widget/SubLayersPopupButton.d.ts.map +0 -1
- package/lib/ui/widget/SubLayersPopupButton.js.map +0 -1
- package/lib/ui/widget/SubLayersTree.d.ts.map +0 -1
- package/lib/ui/widget/SubLayersTree.js.map +0 -1
- package/lib/ui/widget/TransparencyPopupButton.d.ts.map +0 -1
- package/lib/ui/widget/TransparencyPopupButton.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SubLayersDataProvider.js","sourceRoot":"","sources":["../../../../src/ui/widget/SubLayersDataProvider.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\nimport { BeEvent, compareStringsOrUndefined } from \"@itwin/core-bentley\";\r\nimport { MapSubLayerProps, SubLayerId } from \"@itwin/core-common\";\r\nimport { PropertyRecord } from \"@itwin/appui-abstract\";\r\nimport { DelayLoadedTreeNodeItem, ITreeDataProvider, TreeDataChangesListener, TreeNodeItem } from \"@itwin/components-react\";\r\nimport { CheckBoxState } from \"@itwin/core-react\";\r\nimport { StyleMapLayerSettings } from \"../Interfaces\";\r\n\r\n/**\r\n * Data provider that returns some fake nodes to show in tree.\r\n */\r\nexport class SubLayersDataProvider implements ITreeDataProvider {\r\n private readonly _nodeMap = new Map<string, TreeNodeItem[]>();\r\n private readonly _mapLayer: StyleMapLayerSettings;\r\n\r\n constructor(mapLayer: StyleMapLayerSettings) {\r\n this._mapLayer = mapLayer;\r\n this.loadNodes(mapLayer.subLayers);\r\n }\r\n\r\n public static isUnnamedGroup(subLayer: MapSubLayerProps | undefined): boolean {\r\n if (!subLayer)\r\n return false;\r\n\r\n return (!subLayer.name || subLayer.name.length === 0) && (subLayer.children !== undefined && subLayer.children.length > 0);\r\n }\r\n\r\n private createId(props: MapSubLayerProps): string {\r\n return undefined !== props.id ? `${props.id}` : props.name ? props.name : \"no-id\";\r\n }\r\n\r\n private createNode(props: MapSubLayerProps, expanded?: boolean, isCheckboxDisabled?: boolean, icon?: string): DelayLoadedTreeNodeItem {\r\n return {\r\n id: this.createId(props),\r\n label: PropertyRecord.fromString(props.title ?? props.name ?? \"unknown\"),\r\n hasChildren: !!props.children,\r\n isCheckboxVisible: true,\r\n checkBoxState: props.visible && !isCheckboxDisabled ? CheckBoxState.On : CheckBoxState.Off,\r\n extendedData: { subLayerId: props.id },\r\n isCheckboxDisabled,\r\n autoExpand: expanded,\r\n icon,\r\n };\r\n }\r\n\r\n private loadChildNodes(allSubLayers: MapSubLayerProps[], parentId?: SubLayerId) {\r\n const filteredProps = allSubLayers.filter((props) => parentId === props.parent);\r\n if (filteredProps.length) {\r\n filteredProps?.sort((a: MapSubLayerProps, b: MapSubLayerProps) => compareStringsOrUndefined(a.title, b.title));\r\n const treeNodes: TreeNodeItem[] = [];\r\n\r\n filteredProps.forEach((props) => {\r\n treeNodes.push(this.createNode(props,\r\n (!parentId && props?.children !== undefined) ? true : undefined, // expand root group only (i.e. not the entire tree),\r\n undefined,\r\n SubLayersDataProvider.isUnnamedGroup(props) ? \"icon-folder\" : \"icon-layers\"\r\n\r\n ));\r\n if (props.children)\r\n this.loadChildNodes(allSubLayers, props.id);\r\n });\r\n\r\n this._nodeMap.set(undefined !== parentId ? `${parentId}` : \"\", treeNodes);\r\n }\r\n }\r\n\r\n private loadNodes(subLayerNodes: MapSubLayerProps[] | undefined) {\r\n subLayerNodes?.sort((a: MapSubLayerProps, b: MapSubLayerProps) => compareStringsOrUndefined(a.title, b.title));\r\n if (subLayerNodes) {\r\n this.loadChildNodes(subLayerNodes, undefined);\r\n }\r\n }\r\n\r\n public onTreeNodeChanged = new BeEvent<TreeDataChangesListener>();\r\n\r\n public async getNodesCount(parent?: TreeNodeItem) {\r\n const nodeArray: TreeNodeItem[] | undefined = parent ? this._nodeMap.get(parent.id) : this._nodeMap.get(\"\");\r\n if (nodeArray)\r\n return nodeArray.length;\r\n\r\n return 0;\r\n }\r\n\r\n public async getNodes(parent?: TreeNodeItem) {\r\n const nodeArray: TreeNodeItem[] | undefined = parent ? this._nodeMap.get(parent.id) : this._nodeMap.get(\"\");\r\n if (nodeArray)\r\n return nodeArray;\r\n\r\n return [];\r\n }\r\n}\r\n"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import { ScreenViewport } from "@itwin/core-frontend";
|
|
3
|
+
import { StyleMapLayerSettings } from "../Interfaces";
|
|
4
|
+
/** @internal */
|
|
5
|
+
export interface SubLayersPopupButtonProps {
|
|
6
|
+
mapLayerSettings: StyleMapLayerSettings;
|
|
7
|
+
activeViewport: ScreenViewport;
|
|
8
|
+
}
|
|
9
|
+
/** @internal */
|
|
10
|
+
export declare function SubLayersPopupButton({ mapLayerSettings, activeViewport }: SubLayersPopupButtonProps): JSX.Element;
|
|
11
|
+
//# sourceMappingURL=SubLayersPopupButton.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SubLayersPopupButton.d.ts","sourceRoot":"","sources":["../../../../src/ui/widget/SubLayersPopupButton.tsx"],"names":[],"mappings":";AAKA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAItD,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAKtD,gBAAgB;AAChB,MAAM,WAAW,yBAAyB;IACxC,gBAAgB,EAAE,qBAAqB,CAAC;IACxC,cAAc,EAAE,cAAc,CAAC;CAChC;AAED,gBAAgB;AAEhB,wBAAgB,oBAAoB,CAAC,EAAE,gBAAgB,EAAE,cAAc,EAAE,EAAE,yBAAyB,eA0CnG"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/*---------------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
3
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
import * as React from "react";
|
|
6
|
+
import { RelativePosition } from "@itwin/appui-abstract";
|
|
7
|
+
import { Popup, useOnOutsideClick, WebFontIcon } from "@itwin/core-react";
|
|
8
|
+
import { SubLayersPanel } from "./SubLayersTree";
|
|
9
|
+
import { MapLayersUiItemsProvider } from "../MapLayersUiItemsProvider";
|
|
10
|
+
/** @internal */
|
|
11
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
12
|
+
export function SubLayersPopupButton({ mapLayerSettings, activeViewport }) {
|
|
13
|
+
const [showSubLayersLabel] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString("mapLayers:SubLayers.Show"));
|
|
14
|
+
const [hideSubLayersLabel] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString("mapLayers:SubLayers.Hide"));
|
|
15
|
+
const [popupOpen, setPopupOpen] = React.useState(false);
|
|
16
|
+
const buttonRef = React.useRef(null);
|
|
17
|
+
const togglePopup = React.useCallback(() => {
|
|
18
|
+
setPopupOpen(!popupOpen);
|
|
19
|
+
}, [popupOpen]);
|
|
20
|
+
const onOutsideClick = React.useCallback(() => {
|
|
21
|
+
setPopupOpen(false);
|
|
22
|
+
}, []);
|
|
23
|
+
const isOutsideEvent = React.useCallback((e) => {
|
|
24
|
+
// if clicking on button that open panel - don't trigger outside click processing
|
|
25
|
+
return !!buttonRef.current && (e.target instanceof Node) && !buttonRef.current.contains(e.target);
|
|
26
|
+
}, []);
|
|
27
|
+
const panelRef = useOnOutsideClick(onOutsideClick, isOutsideEvent);
|
|
28
|
+
return (React.createElement(React.Fragment, null,
|
|
29
|
+
React.createElement("button", { ref: buttonRef, className: "map-manager-item-sub-layer-button", title: popupOpen ? hideSubLayersLabel : showSubLayersLabel, onClick: togglePopup },
|
|
30
|
+
React.createElement(WebFontIcon, { iconName: "icon-layers" })),
|
|
31
|
+
React.createElement(Popup, { isOpen: popupOpen, position: RelativePosition.BottomRight, onClose: onOutsideClick, target: buttonRef.current },
|
|
32
|
+
React.createElement("div", { className: "map-transparency-popup-panel" },
|
|
33
|
+
React.createElement("div", { ref: panelRef, className: "map-manager-sublayer-panel" },
|
|
34
|
+
React.createElement(SubLayersPanel, { mapLayer: mapLayerSettings, viewport: activeViewport }))))));
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=SubLayersPopupButton.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SubLayersPopupButton.js","sourceRoot":"","sources":["../../../../src/ui/widget/SubLayersPopupButton.tsx"],"names":[],"mappings":"AAAA;;;+FAG+F;AAC/F,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAqB,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAC7F,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEjD,OAAO,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AAUvE,gBAAgB;AAChB,gEAAgE;AAChE,MAAM,UAAU,oBAAoB,CAAC,EAAE,gBAAgB,EAAE,cAAc,EAA6B;IAElG,MAAM,CAAC,kBAAkB,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,wBAAwB,CAAC,YAAY,CAAC,kBAAkB,CAAC,0BAA0B,CAAC,CAAC,CAAC;IAClI,MAAM,CAAC,kBAAkB,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,wBAAwB,CAAC,YAAY,CAAC,kBAAkB,CAAC,0BAA0B,CAAC,CAAC,CAAC;IAClI,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACxD,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAoB,IAAI,CAAC,CAAC;IAExD,MAAM,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE;QACzC,YAAY,CAAC,CAAC,SAAS,CAAC,CAAC;IAC3B,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;IAEhB,MAAM,cAAc,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE;QAC5C,YAAY,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,cAAc,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC,CAAoB,EAAE,EAAE;QAChE,iFAAiF;QACjF,OAAO,CAAC,CAAC,SAAS,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC,MAAM,YAAY,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IACpG,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,QAAQ,GAAG,iBAAiB,CAAiB,cAAc,EAAE,cAAc,CAAC,CAAC;IAEnF,OAAO,CACL;QACE,gCAAQ,GAAG,EAAE,SAAS,EAAE,SAAS,EAAC,mCAAmC,EAAC,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,kBAAkB,EAC9H,OAAO,EAAE,WAAW;YACpB,oBAAC,WAAW,IAAC,QAAQ,EAAC,aAAa,GAAG,CAC/B;QACT,oBAAC,KAAK,IACJ,MAAM,EAAE,SAAS,EACjB,QAAQ,EAAE,gBAAgB,CAAC,WAAW,EACtC,OAAO,EAAE,cAAc,EACvB,MAAM,EAAE,SAAS,CAAC,OAAO;YAEzB,6BAAK,SAAS,EAAC,8BAA8B;gBAC3C,6BAAK,GAAG,EAAE,QAAQ,EAAE,SAAS,EAAC,4BAA4B;oBACxD,oBAAC,cAAc,IAAC,QAAQ,EAAE,gBAAgB,EAAE,QAAQ,EAAE,cAAc,GAAI,CACpE,CACF,CACC,CACR,CACJ,CAAC;AACJ,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\nimport * as React from \"react\";\r\nimport { ScreenViewport } from \"@itwin/core-frontend\";\r\nimport { RelativePosition } from \"@itwin/appui-abstract\";\r\nimport { OutsideClickEvent, Popup, useOnOutsideClick, WebFontIcon } from \"@itwin/core-react\";\r\nimport { SubLayersPanel } from \"./SubLayersTree\";\r\nimport { StyleMapLayerSettings } from \"../Interfaces\";\r\nimport { MapLayersUiItemsProvider } from \"../MapLayersUiItemsProvider\";\r\n\r\n// cSpell:ignore droppable Sublayer\r\n\r\n/** @internal */\r\nexport interface SubLayersPopupButtonProps {\r\n mapLayerSettings: StyleMapLayerSettings;\r\n activeViewport: ScreenViewport;\r\n}\r\n\r\n/** @internal */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport function SubLayersPopupButton({ mapLayerSettings, activeViewport }: SubLayersPopupButtonProps) {\r\n\r\n const [showSubLayersLabel] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString(\"mapLayers:SubLayers.Show\"));\r\n const [hideSubLayersLabel] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString(\"mapLayers:SubLayers.Hide\"));\r\n const [popupOpen, setPopupOpen] = React.useState(false);\r\n const buttonRef = React.useRef<HTMLButtonElement>(null);\r\n\r\n const togglePopup = React.useCallback(() => {\r\n setPopupOpen(!popupOpen);\r\n }, [popupOpen]);\r\n\r\n const onOutsideClick = React.useCallback(() => {\r\n setPopupOpen(false);\r\n }, []);\r\n\r\n const isOutsideEvent = React.useCallback((e: OutsideClickEvent) => {\r\n // if clicking on button that open panel - don't trigger outside click processing\r\n return !!buttonRef.current && (e.target instanceof Node) && !buttonRef.current.contains(e.target);\r\n }, []);\r\n\r\n const panelRef = useOnOutsideClick<HTMLDivElement>(onOutsideClick, isOutsideEvent);\r\n\r\n return (\r\n <>\r\n <button ref={buttonRef} className=\"map-manager-item-sub-layer-button\" title={popupOpen ? hideSubLayersLabel : showSubLayersLabel}\r\n onClick={togglePopup}>\r\n <WebFontIcon iconName=\"icon-layers\" />\r\n </button>\r\n <Popup\r\n isOpen={popupOpen}\r\n position={RelativePosition.BottomRight}\r\n onClose={onOutsideClick}\r\n target={buttonRef.current}\r\n >\r\n <div className=\"map-transparency-popup-panel\">\r\n <div ref={panelRef} className=\"map-manager-sublayer-panel\">\r\n <SubLayersPanel mapLayer={mapLayerSettings} viewport={activeViewport} />\r\n </div>\r\n </div>\r\n </Popup >\r\n </>\r\n );\r\n}\r\n"]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import { ScreenViewport } from "@itwin/core-frontend";
|
|
3
|
+
import { StyleMapLayerSettings } from "../Interfaces";
|
|
4
|
+
import "./SubLayersTree.scss";
|
|
5
|
+
export declare function SubLayersPanel({ mapLayer, viewport }: {
|
|
6
|
+
mapLayer: StyleMapLayerSettings;
|
|
7
|
+
viewport: ScreenViewport | undefined;
|
|
8
|
+
}): JSX.Element;
|
|
9
|
+
/**
|
|
10
|
+
* Tree Control that displays sub-layer hierarchy
|
|
11
|
+
* @internal
|
|
12
|
+
*/
|
|
13
|
+
export declare function SubLayersTree(props: {
|
|
14
|
+
mapLayer: StyleMapLayerSettings;
|
|
15
|
+
}): JSX.Element;
|
|
16
|
+
//# sourceMappingURL=SubLayersTree.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SubLayersTree.d.ts","sourceRoot":"","sources":["../../../../src/ui/widget/SubLayersTree.tsx"],"names":[],"mappings":";AAMA,OAAO,EAAa,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAYjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAGtD,OAAO,sBAAsB,CAAC;AAsB9B,wBAAgB,cAAc,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,qBAAqB,CAAC;IAAC,QAAQ,EAAE,cAAc,GAAG,SAAS,CAAA;CAAE,eAW/H;AAoBD;;;GAGG;AAEH,wBAAgB,aAAa,CAAC,KAAK,EAAE;IAAE,QAAQ,EAAE,qBAAqB,CAAA;CAAE,eA8FvE"}
|
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
/*---------------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
3
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
import * as React from "react";
|
|
6
|
+
import { useResizeDetector } from "react-resize-detector";
|
|
7
|
+
import { IModelApp } from "@itwin/core-frontend";
|
|
8
|
+
import { PropertyValueFormat } from "@itwin/appui-abstract";
|
|
9
|
+
import { CheckBoxState, ImageCheckBox, useDisposable, WebFontIcon } from "@itwin/core-react";
|
|
10
|
+
import { ControlledTree, SelectionMode, TreeEventHandler, TreeImageLoader, TreeModelSource, TreeNodeLoader, TreeNodeRenderer, TreeRenderer, useTreeModel, } from "@itwin/components-react";
|
|
11
|
+
import { Input } from "@itwin/itwinui-react";
|
|
12
|
+
import { SubLayersDataProvider } from "./SubLayersDataProvider";
|
|
13
|
+
import { MapLayersUiItemsProvider } from "../MapLayersUiItemsProvider";
|
|
14
|
+
import "./SubLayersTree.scss";
|
|
15
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
16
|
+
function Toolbar(props) {
|
|
17
|
+
return (React.createElement("div", { className: "map-manager-sublayer-tree-toolbar" },
|
|
18
|
+
React.createElement("div", { className: "tree-toolbar-action-buttons" }, props.children),
|
|
19
|
+
props.searchField && React.createElement("div", { className: "tree-toolbar-searchbox" }, props.searchField)));
|
|
20
|
+
}
|
|
21
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
22
|
+
export function SubLayersPanel({ mapLayer, viewport }) {
|
|
23
|
+
const [noneAvailableLabel] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString("mapLayers:SubLayers.NoSubLayers"));
|
|
24
|
+
if (!viewport || (undefined === mapLayer.subLayers || 0 === mapLayer.subLayers.length)) {
|
|
25
|
+
return React.createElement("div", { className: "map-manager-sublayer-panel" },
|
|
26
|
+
React.createElement("div", null, noneAvailableLabel));
|
|
27
|
+
}
|
|
28
|
+
return (React.createElement(SubLayersTree, { mapLayer: mapLayer }));
|
|
29
|
+
}
|
|
30
|
+
function getSubLayerProps(subLayerSettings) {
|
|
31
|
+
return subLayerSettings.map((subLayer) => subLayer.toJSON());
|
|
32
|
+
}
|
|
33
|
+
function getStyleMapLayerSettings(settings, isOverlay) {
|
|
34
|
+
return {
|
|
35
|
+
visible: settings.visible,
|
|
36
|
+
name: settings.name,
|
|
37
|
+
url: settings.url,
|
|
38
|
+
transparency: settings.transparency,
|
|
39
|
+
transparentBackground: settings.transparentBackground,
|
|
40
|
+
subLayers: settings.subLayers ? getSubLayerProps(settings.subLayers) : undefined,
|
|
41
|
+
showSubLayers: true,
|
|
42
|
+
isOverlay,
|
|
43
|
+
provider: IModelApp.mapLayerFormatRegistry.createImageryProvider(settings),
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Tree Control that displays sub-layer hierarchy
|
|
48
|
+
* @internal
|
|
49
|
+
*/
|
|
50
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
51
|
+
export function SubLayersTree(props) {
|
|
52
|
+
var _a;
|
|
53
|
+
const [placeholderLabel] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString("mapLayers:SubLayers.SearchPlaceholder"));
|
|
54
|
+
const [allOnLabel] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString("mapLayers:SubLayers.AllOn"));
|
|
55
|
+
const [allOffLabel] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString("mapLayers:SubLayers.AllOff"));
|
|
56
|
+
const [mapLayer, setMapLayer] = React.useState(props.mapLayer);
|
|
57
|
+
const [layerFilterString, setLayerFilterString] = React.useState("");
|
|
58
|
+
// create data provider to get some nodes to show in tree
|
|
59
|
+
// `React.useMemo' is used avoid creating new object on each render cycle
|
|
60
|
+
const dataProvider = React.useMemo(() => new SubLayersDataProvider(mapLayer), [mapLayer]);
|
|
61
|
+
const { modelSource, nodeLoader, nodeHighlightingProps, } = useTreeFiltering(dataProvider, layerFilterString);
|
|
62
|
+
// create custom event handler. It handles all tree event same as `TreeEventHandler` but additionally
|
|
63
|
+
// it selects/deselects node when checkbox is checked/unchecked and vice versa.
|
|
64
|
+
// `useDisposable` takes care of disposing old event handler when new is created in case 'nodeLoader' has changed
|
|
65
|
+
// `React.useCallback` is used to avoid creating new callback that creates handler on each render
|
|
66
|
+
const eventHandler = useDisposable(React.useCallback(() => new SubLayerCheckboxHandler(mapLayer, nodeLoader), [nodeLoader, mapLayer]));
|
|
67
|
+
// Get an immutable tree model from the model source. The model is regenerated every time the model source
|
|
68
|
+
// emits the `onModelChanged` event.
|
|
69
|
+
const treeModel = useTreeModel(modelSource);
|
|
70
|
+
const showAll = React.useCallback(async () => {
|
|
71
|
+
const vp = IModelApp.viewManager.selectedView;
|
|
72
|
+
const displayStyle = vp === null || vp === void 0 ? void 0 : vp.displayStyle;
|
|
73
|
+
if (displayStyle && vp) {
|
|
74
|
+
const indexInDisplayStyle = displayStyle ? displayStyle.findMapLayerIndexByNameAndUrl(mapLayer.name, mapLayer.url, mapLayer.isOverlay) : -1;
|
|
75
|
+
displayStyle.changeMapSubLayerProps({ visible: true }, -1, indexInDisplayStyle, mapLayer.isOverlay);
|
|
76
|
+
vp.invalidateRenderPlan();
|
|
77
|
+
const updatedMapLayer = displayStyle.mapLayerAtIndex(indexInDisplayStyle, mapLayer.isOverlay);
|
|
78
|
+
if (updatedMapLayer) {
|
|
79
|
+
setMapLayer(getStyleMapLayerSettings(updatedMapLayer, mapLayer.isOverlay));
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}, [mapLayer]);
|
|
83
|
+
const hideAll = React.useCallback(async () => {
|
|
84
|
+
const vp = IModelApp.viewManager.selectedView;
|
|
85
|
+
const displayStyle = vp === null || vp === void 0 ? void 0 : vp.displayStyle;
|
|
86
|
+
if (displayStyle && vp) {
|
|
87
|
+
const indexInDisplayStyle = displayStyle ? displayStyle.findMapLayerIndexByNameAndUrl(mapLayer.name, mapLayer.url, mapLayer.isOverlay) : -1;
|
|
88
|
+
displayStyle.changeMapSubLayerProps({ visible: false }, -1, indexInDisplayStyle, mapLayer.isOverlay);
|
|
89
|
+
const updatedMapLayer = displayStyle.mapLayerAtIndex(indexInDisplayStyle, mapLayer.isOverlay);
|
|
90
|
+
if (updatedMapLayer) {
|
|
91
|
+
setMapLayer(getStyleMapLayerSettings(updatedMapLayer, mapLayer.isOverlay));
|
|
92
|
+
}
|
|
93
|
+
vp.invalidateRenderPlan();
|
|
94
|
+
}
|
|
95
|
+
}, [mapLayer]);
|
|
96
|
+
const handleFilterTextChanged = React.useCallback((event) => {
|
|
97
|
+
setLayerFilterString(event.target.value);
|
|
98
|
+
}, []);
|
|
99
|
+
const { width, height, ref } = useResizeDetector();
|
|
100
|
+
return React.createElement(React.Fragment, null,
|
|
101
|
+
React.createElement("div", { className: "map-manager-sublayer-tree" },
|
|
102
|
+
React.createElement(Toolbar, { searchField: React.createElement(Input, { type: "text", className: "map-manager-source-list-filter", placeholder: placeholderLabel, value: layerFilterString, onChange: handleFilterTextChanged }) }, ((_a = mapLayer.provider) === null || _a === void 0 ? void 0 : _a.mutualExclusiveSubLayer) ? undefined : [
|
|
103
|
+
React.createElement("button", { key: "show-all-btn", title: allOnLabel, onClick: showAll },
|
|
104
|
+
React.createElement(WebFontIcon, { iconName: "icon-visibility" })),
|
|
105
|
+
React.createElement("button", { key: "hide-all-btn", title: allOffLabel, onClick: hideAll },
|
|
106
|
+
React.createElement(WebFontIcon, { iconName: "icon-visibility-hide-2" })),
|
|
107
|
+
]),
|
|
108
|
+
React.createElement("div", { ref: ref, className: "map-manager-sublayer-tree-content" }, width && height ? React.createElement(ControlledTree, { nodeLoader: nodeLoader, selectionMode: SelectionMode.None, eventsHandler: eventHandler, model: treeModel, treeRenderer: nodeWithEyeCheckboxTreeRenderer, nodeHighlightingProps: nodeHighlightingProps, width: width, height: height }) : null)));
|
|
109
|
+
}
|
|
110
|
+
/** TreeEventHandler derived class that handler processing changes to subLayer visibility */
|
|
111
|
+
class SubLayerCheckboxHandler extends TreeEventHandler {
|
|
112
|
+
constructor(_mapLayer, nodeLoader) {
|
|
113
|
+
super({ modelSource: nodeLoader.modelSource, nodeLoader, collapsedChildrenDisposalEnabled: true });
|
|
114
|
+
this._mapLayer = _mapLayer;
|
|
115
|
+
//-----------------------------------------------------------------------
|
|
116
|
+
// Listen to model changes
|
|
117
|
+
//------------------------------------------------------------------------
|
|
118
|
+
// This is required because nodes are delay loaded in the model until
|
|
119
|
+
// they are made visible (i.e. parent node is expanded). So even though
|
|
120
|
+
// you might have created nodes in the data provided with a proper
|
|
121
|
+
// initial state, by the time it gets loaded, their state might have became
|
|
122
|
+
// out of date in the TreeView's active model. So whenever a node
|
|
123
|
+
// is added, when must confirm its state matches the current model
|
|
124
|
+
// (i.e. state of their parent.)
|
|
125
|
+
this.onModelChanged = (args) => {
|
|
126
|
+
this.modelSource.modifyModel((model) => {
|
|
127
|
+
const addedNodes = args[1].addedNodeIds.map((id) => model.getNode(id));
|
|
128
|
+
addedNodes.forEach((node) => {
|
|
129
|
+
if (!node)
|
|
130
|
+
return;
|
|
131
|
+
this.syncNodeStateWithParent(model, node);
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
};
|
|
135
|
+
this._removeModelChangedListener = this.modelSource.onModelChanged.addListener(this.onModelChanged);
|
|
136
|
+
}
|
|
137
|
+
dispose() {
|
|
138
|
+
this._removeModelChangedListener();
|
|
139
|
+
super.dispose();
|
|
140
|
+
}
|
|
141
|
+
// Cascade state
|
|
142
|
+
// Children on unnamed groups must get disabled in the tree view, because
|
|
143
|
+
// they get rendered anyway.
|
|
144
|
+
cascadeStateToAllChildren(model, parentId) {
|
|
145
|
+
const children = model.getChildren(parentId);
|
|
146
|
+
if (children === undefined)
|
|
147
|
+
return;
|
|
148
|
+
for (const childID of children) {
|
|
149
|
+
const childNode = childID ? model.getNode(childID) : undefined;
|
|
150
|
+
if (childNode)
|
|
151
|
+
this.syncNodeStateWithParent(model, childNode);
|
|
152
|
+
// Drill down the tree.
|
|
153
|
+
this.cascadeStateToAllChildren(model, childID);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
applyMutualExclusiveState(model, nodeId) {
|
|
157
|
+
const changedNode = model.getNode(nodeId);
|
|
158
|
+
if ((changedNode === null || changedNode === void 0 ? void 0 : changedNode.checkbox.state) === CheckBoxState.Off)
|
|
159
|
+
return;
|
|
160
|
+
for (const node of model.iterateTreeModelNodes()) {
|
|
161
|
+
if (node.id === (changedNode === null || changedNode === void 0 ? void 0 : changedNode.id))
|
|
162
|
+
continue;
|
|
163
|
+
if (node && node.checkbox.state === CheckBoxState.On)
|
|
164
|
+
node.checkbox.state = CheckBoxState.Off;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
static isUnnamedGroup(subLayer) {
|
|
168
|
+
if (!subLayer)
|
|
169
|
+
return false;
|
|
170
|
+
return (!subLayer.name || subLayer.name.length === 0) && (subLayer.children !== undefined && subLayer.children.length > 0);
|
|
171
|
+
}
|
|
172
|
+
// Ensure the state of changed node matches the state of its parent.
|
|
173
|
+
syncNodeStateWithParent(model, changedNode) {
|
|
174
|
+
var _a, _b, _c, _d, _e, _f;
|
|
175
|
+
// Lookup node parent. If non exists, I assume thats the root node,
|
|
176
|
+
// and it must have a proper initial state.
|
|
177
|
+
const parentNode = changedNode.parentId ? model.getNode(changedNode.parentId) : undefined;
|
|
178
|
+
if (!parentNode)
|
|
179
|
+
return;
|
|
180
|
+
if (!changedNode.checkbox)
|
|
181
|
+
return; // don't see why this would happen, but if there is no checkbox, we cant do much here.
|
|
182
|
+
const parentLayerId = undefined !== ((_a = parentNode.item.extendedData) === null || _a === void 0 ? void 0 : _a.subLayerId) ? (_b = parentNode.item.extendedData) === null || _b === void 0 ? void 0 : _b.subLayerId : parentNode.item.id;
|
|
183
|
+
const parentSubLayer = (_c = this._mapLayer.subLayers) === null || _c === void 0 ? void 0 : _c.find((subLayer) => subLayer.id === parentLayerId);
|
|
184
|
+
// If parent is disabled, then children must be too.
|
|
185
|
+
// Also, Non-visible unnamed group must have their children disabled (unamed groups have visibility inherence)
|
|
186
|
+
if (parentNode.checkbox.isDisabled || (SubLayerCheckboxHandler.isUnnamedGroup(parentSubLayer) && parentNode.checkbox.state === CheckBoxState.Off)) {
|
|
187
|
+
changedNode.checkbox.isDisabled = true;
|
|
188
|
+
changedNode.checkbox.state = CheckBoxState.Off;
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
// Visibility state from StyleMapLayerSettings applies
|
|
192
|
+
const subLayerId = undefined !== ((_d = changedNode.item.extendedData) === null || _d === void 0 ? void 0 : _d.subLayerId) ? (_e = changedNode.item.extendedData) === null || _e === void 0 ? void 0 : _e.subLayerId : changedNode.item.id;
|
|
193
|
+
const foundSubLayer = (_f = this._mapLayer.subLayers) === null || _f === void 0 ? void 0 : _f.find((subLayer) => subLayer.id === subLayerId);
|
|
194
|
+
changedNode.checkbox.isDisabled = false;
|
|
195
|
+
changedNode.checkbox.state = (foundSubLayer === null || foundSubLayer === void 0 ? void 0 : foundSubLayer.visible) ? CheckBoxState.On : CheckBoxState.Off;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
/** Changes nodes checkboxes states until event is handled or handler is disposed */
|
|
199
|
+
onCheckboxStateChanged({ stateChanges }) {
|
|
200
|
+
// call base checkbox handling
|
|
201
|
+
const baseHandling = super.onCheckboxStateChanged({ stateChanges });
|
|
202
|
+
// subscribe to checkbox state changes to new checkbox states and do some additional work with them
|
|
203
|
+
const selectionHandling = stateChanges.subscribe({
|
|
204
|
+
next: (changes) => {
|
|
205
|
+
const vp = IModelApp.viewManager.selectedView;
|
|
206
|
+
const displayStyle = vp === null || vp === void 0 ? void 0 : vp.displayStyle;
|
|
207
|
+
const indexInDisplayStyle = displayStyle ? displayStyle.findMapLayerIndexByNameAndUrl(this._mapLayer.name, this._mapLayer.url, this._mapLayer.isOverlay) : -1;
|
|
208
|
+
changes.forEach((change) => {
|
|
209
|
+
var _a, _b, _c, _d, _e;
|
|
210
|
+
const isSelected = (change.newState === CheckBoxState.On);
|
|
211
|
+
const subLayerId = undefined !== ((_a = change.nodeItem.extendedData) === null || _a === void 0 ? void 0 : _a.subLayerId) ? (_b = change.nodeItem.extendedData) === null || _b === void 0 ? void 0 : _b.subLayerId : change.nodeItem.id;
|
|
212
|
+
// Get the previously visible node if any
|
|
213
|
+
let prevVisibleLayer;
|
|
214
|
+
if ((_c = this._mapLayer.provider) === null || _c === void 0 ? void 0 : _c.mutualExclusiveSubLayer) {
|
|
215
|
+
prevVisibleLayer = (_d = this._mapLayer.subLayers) === null || _d === void 0 ? void 0 : _d.find((subLayer) => subLayer.visible && subLayer.id !== subLayerId);
|
|
216
|
+
}
|
|
217
|
+
// Update sublayer object, otherwise state would get out of sync with DisplayStyle each time the TreeView is re-rendered
|
|
218
|
+
const foundSubLayer = (_e = this._mapLayer.subLayers) === null || _e === void 0 ? void 0 : _e.find((subLayer) => subLayer.id === subLayerId);
|
|
219
|
+
if (foundSubLayer)
|
|
220
|
+
foundSubLayer.visible = isSelected;
|
|
221
|
+
if (prevVisibleLayer === null || prevVisibleLayer === void 0 ? void 0 : prevVisibleLayer.visible)
|
|
222
|
+
prevVisibleLayer.visible = false;
|
|
223
|
+
// Update displaystyle state
|
|
224
|
+
if (-1 !== indexInDisplayStyle && displayStyle) {
|
|
225
|
+
if (prevVisibleLayer && prevVisibleLayer.id !== undefined)
|
|
226
|
+
displayStyle.changeMapSubLayerProps({ visible: false }, prevVisibleLayer.id, indexInDisplayStyle, this._mapLayer.isOverlay);
|
|
227
|
+
displayStyle.changeMapSubLayerProps({ visible: isSelected }, subLayerId, indexInDisplayStyle, this._mapLayer.isOverlay);
|
|
228
|
+
}
|
|
229
|
+
// Cascade state
|
|
230
|
+
this.modelSource.modifyModel((model) => {
|
|
231
|
+
var _a;
|
|
232
|
+
if ((_a = this._mapLayer.provider) === null || _a === void 0 ? void 0 : _a.mutualExclusiveSubLayer)
|
|
233
|
+
this.applyMutualExclusiveState(model, change.nodeItem.id);
|
|
234
|
+
this.cascadeStateToAllChildren(model, change.nodeItem.id);
|
|
235
|
+
});
|
|
236
|
+
});
|
|
237
|
+
if (vp)
|
|
238
|
+
vp.invalidateRenderPlan();
|
|
239
|
+
},
|
|
240
|
+
});
|
|
241
|
+
// stop handling selection when checkboxes handling is stopped
|
|
242
|
+
baseHandling === null || baseHandling === void 0 ? void 0 : baseHandling.add(selectionHandling);
|
|
243
|
+
return baseHandling;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
/** Custom checkbox renderer that renders checkbox as an eye */
|
|
247
|
+
const eyeCheckboxRenderer = (props) => (React.createElement(ImageCheckBox, { checked: props.checked, disabled: props.disabled, imageOn: "icon-visibility", imageOff: "icon-visibility-hide-2", onClick: props.onChange, tooltip: props.title }));
|
|
248
|
+
/** Custom node renderer. It uses default 'TreeNodeRenderer' but overrides default checkbox renderer to render checkbox as an eye */
|
|
249
|
+
const imageLoader = new TreeImageLoader();
|
|
250
|
+
const nodeWithEyeCheckboxRenderer = (props) => (React.createElement(TreeNodeRenderer, Object.assign({}, props, { checkboxRenderer: eyeCheckboxRenderer, imageLoader: imageLoader })));
|
|
251
|
+
/** Custom tree renderer. It uses default `TreeRenderer` but overrides default node renderer to render node with custom checkbox */
|
|
252
|
+
const nodeWithEyeCheckboxTreeRenderer = (props) => (React.createElement(TreeRenderer, Object.assign({}, props, { nodeRenderer: nodeWithEyeCheckboxRenderer })));
|
|
253
|
+
function useTreeFiltering(dataProvider, filter) {
|
|
254
|
+
const nodeLoader = useFilteredProvider(dataProvider, filter);
|
|
255
|
+
const nodeHighlightingProps = useNodeHighlightingProps(filter);
|
|
256
|
+
return {
|
|
257
|
+
nodeLoader,
|
|
258
|
+
modelSource: nodeLoader.modelSource,
|
|
259
|
+
nodeHighlightingProps,
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
function useFilteredProvider(dataProvider, filter) {
|
|
263
|
+
const filteredProvider = React.useMemo(() => {
|
|
264
|
+
return new FilteredTreeDataProvider(dataProvider, filter);
|
|
265
|
+
}, [dataProvider, filter]);
|
|
266
|
+
const nodeLoader = React.useMemo(() => {
|
|
267
|
+
return new TreeNodeLoader(filteredProvider, new TreeModelSource());
|
|
268
|
+
}, [filteredProvider]);
|
|
269
|
+
return nodeLoader;
|
|
270
|
+
}
|
|
271
|
+
function useNodeHighlightingProps(filter) {
|
|
272
|
+
const [nodeHighlightingProps, setNodeHighlightingProps] = React.useState();
|
|
273
|
+
React.useEffect(() => {
|
|
274
|
+
if (filter === "") {
|
|
275
|
+
setNodeHighlightingProps(undefined);
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
setNodeHighlightingProps({
|
|
279
|
+
searchText: filter,
|
|
280
|
+
activeMatch: undefined,
|
|
281
|
+
});
|
|
282
|
+
}, [filter]);
|
|
283
|
+
return nodeHighlightingProps;
|
|
284
|
+
}
|
|
285
|
+
class FullTreeHierarchy {
|
|
286
|
+
constructor(dataProvider) {
|
|
287
|
+
this._hierarchy = new Map();
|
|
288
|
+
this._dataProvider = dataProvider;
|
|
289
|
+
this._init = (async () => {
|
|
290
|
+
await this.initNode();
|
|
291
|
+
})();
|
|
292
|
+
}
|
|
293
|
+
async initNode(parent) {
|
|
294
|
+
const nodes = await this._dataProvider.getNodes(parent);
|
|
295
|
+
this._hierarchy.set(parent === null || parent === void 0 ? void 0 : parent.id, nodes);
|
|
296
|
+
for (const node of nodes) {
|
|
297
|
+
await this.initNode(node);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
async getHierarchy() {
|
|
301
|
+
await this._init;
|
|
302
|
+
return this._hierarchy;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
class FilteredTreeHierarchy {
|
|
306
|
+
constructor(dataProvider, filter) {
|
|
307
|
+
this._filtered = new Map();
|
|
308
|
+
this._fullHierarchy = new FullTreeHierarchy(dataProvider);
|
|
309
|
+
this._filter = filter;
|
|
310
|
+
this._init = (async () => {
|
|
311
|
+
await this.init();
|
|
312
|
+
})();
|
|
313
|
+
}
|
|
314
|
+
async init() {
|
|
315
|
+
const hierarchy = await this._fullHierarchy.getHierarchy();
|
|
316
|
+
if (this._filter === "") {
|
|
317
|
+
this._filtered = hierarchy;
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
this.filterNodes(hierarchy);
|
|
321
|
+
}
|
|
322
|
+
/** Initializes `this._filtered` field. Returns a node if it matches a filter. */
|
|
323
|
+
filterNodes(hierarchy, current) {
|
|
324
|
+
const matches = current ? this.matchesFilter(current) : false;
|
|
325
|
+
const children = hierarchy.get(current === null || current === void 0 ? void 0 : current.id);
|
|
326
|
+
if (!children)
|
|
327
|
+
return matches ? current : undefined;
|
|
328
|
+
const matchedChildren = new Array();
|
|
329
|
+
for (const child of children) {
|
|
330
|
+
const matchedChild = this.filterNodes(hierarchy, child);
|
|
331
|
+
matchedChild && matchedChildren.push(matchedChild);
|
|
332
|
+
}
|
|
333
|
+
const hasChildren = matchedChildren.length > 0;
|
|
334
|
+
const included = matches || hasChildren;
|
|
335
|
+
let filtered;
|
|
336
|
+
if (included) {
|
|
337
|
+
this._filtered.set(current === null || current === void 0 ? void 0 : current.id, matchedChildren);
|
|
338
|
+
// Return a modified copy of current node (to persist initial hierarchy when filter is cleared).
|
|
339
|
+
if (current) {
|
|
340
|
+
filtered = Object.assign(Object.assign({}, current), { hasChildren, autoExpand: hasChildren ? true : current.autoExpand });
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
return filtered;
|
|
344
|
+
}
|
|
345
|
+
matchesFilter(node) {
|
|
346
|
+
var _a;
|
|
347
|
+
if (node.label.value.valueFormat !== PropertyValueFormat.Primitive)
|
|
348
|
+
return false;
|
|
349
|
+
const value = (_a = node.label.value.displayValue) === null || _a === void 0 ? void 0 : _a.toLowerCase();
|
|
350
|
+
if (!value)
|
|
351
|
+
return false;
|
|
352
|
+
return value.includes(this._filter.toLowerCase());
|
|
353
|
+
}
|
|
354
|
+
async getHierarchy() {
|
|
355
|
+
await this._init;
|
|
356
|
+
return this._filtered;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
class FilteredTreeDataProvider {
|
|
360
|
+
constructor(parentDataProvider, filter) {
|
|
361
|
+
this._hierarchy = new FilteredTreeHierarchy(parentDataProvider, filter);
|
|
362
|
+
}
|
|
363
|
+
async getNodes(parent) {
|
|
364
|
+
const hierarchy = await this._hierarchy.getHierarchy();
|
|
365
|
+
const nodes = hierarchy.get(parent === null || parent === void 0 ? void 0 : parent.id);
|
|
366
|
+
return nodes || [];
|
|
367
|
+
}
|
|
368
|
+
async getNodesCount(parent) {
|
|
369
|
+
const hierarchy = await this._hierarchy.getHierarchy();
|
|
370
|
+
const nodes = hierarchy.get(parent === null || parent === void 0 ? void 0 : parent.id);
|
|
371
|
+
return (nodes === null || nodes === void 0 ? void 0 : nodes.length) || 0;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
//# sourceMappingURL=SubLayersTree.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SubLayersTree.js","sourceRoot":"","sources":["../../../../src/ui/widget/SubLayersTree.tsx"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\nimport * as React from \"react\";\r\nimport { useResizeDetector } from \"react-resize-detector\";\r\nimport { IModelApp, ScreenViewport } from \"@itwin/core-frontend\";\r\nimport { PropertyValueFormat } from \"@itwin/appui-abstract\";\r\nimport { CheckBoxState, ImageCheckBox, NodeCheckboxRenderProps, useDisposable, WebFontIcon } from \"@itwin/core-react\";\r\nimport {\r\n AbstractTreeNodeLoaderWithProvider, ControlledTree, DelayLoadedTreeNodeItem, HighlightableTreeProps, ITreeDataProvider,\r\n MutableTreeModel,\r\n MutableTreeModelNode,\r\n SelectionMode, TreeCheckboxStateChangeEventArgs, TreeDataProvider, TreeEventHandler, TreeImageLoader, TreeModel, TreeModelChanges, TreeModelSource, TreeNodeItem, TreeNodeLoader,\r\n TreeNodeRenderer, TreeNodeRendererProps, TreeRenderer, TreeRendererProps, useTreeModel,\r\n} from \"@itwin/components-react\";\r\nimport { MapLayerSettings, MapSubLayerProps, MapSubLayerSettings } from \"@itwin/core-common\";\r\nimport { Input } from \"@itwin/itwinui-react\";\r\nimport { StyleMapLayerSettings } from \"../Interfaces\";\r\nimport { SubLayersDataProvider } from \"./SubLayersDataProvider\";\r\nimport { MapLayersUiItemsProvider } from \"../MapLayersUiItemsProvider\";\r\nimport \"./SubLayersTree.scss\";\r\n\r\ninterface ToolbarProps {\r\n searchField?: React.ReactNode;\r\n children?: React.ReactNode[];\r\n}\r\n\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nfunction Toolbar(props: ToolbarProps) {\r\n return (\r\n <div className=\"map-manager-sublayer-tree-toolbar\">\r\n <div className=\"tree-toolbar-action-buttons\">\r\n {props.children}\r\n </div>\r\n {props.searchField && <div className=\"tree-toolbar-searchbox\">\r\n {props.searchField}\r\n </div>}\r\n </div>\r\n );\r\n}\r\n\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport function SubLayersPanel({ mapLayer, viewport }: { mapLayer: StyleMapLayerSettings, viewport: ScreenViewport | undefined }) {\r\n const [noneAvailableLabel] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString(\"mapLayers:SubLayers.NoSubLayers\"));\r\n if (!viewport || (undefined === mapLayer.subLayers || 0 === mapLayer.subLayers.length)) {\r\n return <div className=\"map-manager-sublayer-panel\">\r\n <div>{noneAvailableLabel}</div>\r\n </div>;\r\n }\r\n\r\n return (\r\n <SubLayersTree mapLayer={mapLayer} />\r\n );\r\n}\r\n\r\nfunction getSubLayerProps(subLayerSettings: MapSubLayerSettings[]): MapSubLayerProps[] {\r\n return subLayerSettings.map((subLayer) => subLayer.toJSON());\r\n}\r\n\r\nfunction getStyleMapLayerSettings(settings: MapLayerSettings, isOverlay: boolean): StyleMapLayerSettings {\r\n return {\r\n visible: settings.visible,\r\n name: settings.name,\r\n url: settings.url,\r\n transparency: settings.transparency,\r\n transparentBackground: settings.transparentBackground,\r\n subLayers: settings.subLayers ? getSubLayerProps(settings.subLayers) : undefined,\r\n showSubLayers: true,\r\n isOverlay,\r\n provider: IModelApp.mapLayerFormatRegistry.createImageryProvider(settings),\r\n };\r\n}\r\n\r\n/**\r\n * Tree Control that displays sub-layer hierarchy\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport function SubLayersTree(props: { mapLayer: StyleMapLayerSettings }) {\r\n const [placeholderLabel] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString(\"mapLayers:SubLayers.SearchPlaceholder\"));\r\n const [allOnLabel] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString(\"mapLayers:SubLayers.AllOn\"));\r\n const [allOffLabel] = React.useState(MapLayersUiItemsProvider.localization.getLocalizedString(\"mapLayers:SubLayers.AllOff\"));\r\n const [mapLayer, setMapLayer] = React.useState(props.mapLayer);\r\n const [layerFilterString, setLayerFilterString] = React.useState<string>(\"\");\r\n\r\n // create data provider to get some nodes to show in tree\r\n // `React.useMemo' is used avoid creating new object on each render cycle\r\n const dataProvider = React.useMemo(() => new SubLayersDataProvider(mapLayer), [mapLayer]);\r\n\r\n const {\r\n modelSource,\r\n nodeLoader,\r\n nodeHighlightingProps,\r\n } = useTreeFiltering(dataProvider, layerFilterString);\r\n\r\n // create custom event handler. It handles all tree event same as `TreeEventHandler` but additionally\r\n // it selects/deselects node when checkbox is checked/unchecked and vice versa.\r\n // `useDisposable` takes care of disposing old event handler when new is created in case 'nodeLoader' has changed\r\n // `React.useCallback` is used to avoid creating new callback that creates handler on each render\r\n const eventHandler = useDisposable(React.useCallback(() => new SubLayerCheckboxHandler(mapLayer, nodeLoader), [nodeLoader, mapLayer]));\r\n\r\n // Get an immutable tree model from the model source. The model is regenerated every time the model source\r\n // emits the `onModelChanged` event.\r\n const treeModel = useTreeModel(modelSource);\r\n\r\n const showAll = React.useCallback(async () => {\r\n const vp = IModelApp.viewManager.selectedView;\r\n const displayStyle = vp?.displayStyle;\r\n if (displayStyle && vp) {\r\n const indexInDisplayStyle = displayStyle ? displayStyle.findMapLayerIndexByNameAndUrl(mapLayer.name, mapLayer.url, mapLayer.isOverlay) : -1;\r\n displayStyle.changeMapSubLayerProps({ visible: true }, -1, indexInDisplayStyle, mapLayer.isOverlay);\r\n vp.invalidateRenderPlan();\r\n const updatedMapLayer = displayStyle.mapLayerAtIndex(indexInDisplayStyle, mapLayer.isOverlay);\r\n if (updatedMapLayer) {\r\n setMapLayer(getStyleMapLayerSettings(updatedMapLayer, mapLayer.isOverlay));\r\n }\r\n }\r\n }, [mapLayer]);\r\n\r\n const hideAll = React.useCallback(async () => {\r\n const vp = IModelApp.viewManager.selectedView;\r\n const displayStyle = vp?.displayStyle;\r\n if (displayStyle && vp) {\r\n const indexInDisplayStyle = displayStyle ? displayStyle.findMapLayerIndexByNameAndUrl(mapLayer.name, mapLayer.url, mapLayer.isOverlay) : -1;\r\n displayStyle.changeMapSubLayerProps({ visible: false }, -1, indexInDisplayStyle, mapLayer.isOverlay);\r\n const updatedMapLayer = displayStyle.mapLayerAtIndex(indexInDisplayStyle, mapLayer.isOverlay);\r\n if (updatedMapLayer) {\r\n setMapLayer(getStyleMapLayerSettings(updatedMapLayer, mapLayer.isOverlay));\r\n }\r\n vp.invalidateRenderPlan();\r\n }\r\n }, [mapLayer]);\r\n\r\n const handleFilterTextChanged = React.useCallback((event: React.ChangeEvent<HTMLInputElement>) => {\r\n setLayerFilterString(event.target.value);\r\n }, []);\r\n\r\n const { width, height, ref } = useResizeDetector();\r\n\r\n return <>\r\n <div className=\"map-manager-sublayer-tree\">\r\n <Toolbar\r\n searchField={\r\n <Input type=\"text\" className=\"map-manager-source-list-filter\"\r\n placeholder={placeholderLabel}\r\n value={layerFilterString}\r\n onChange={handleFilterTextChanged} />\r\n }\r\n >\r\n {mapLayer.provider?.mutualExclusiveSubLayer ? undefined : [\r\n <button key=\"show-all-btn\" title={allOnLabel} onClick={showAll}>\r\n <WebFontIcon iconName=\"icon-visibility\" />\r\n </button>,\r\n <button key=\"hide-all-btn\" title={allOffLabel} onClick={hideAll}>\r\n <WebFontIcon iconName=\"icon-visibility-hide-2\" />\r\n </button>,\r\n ]}\r\n </Toolbar>\r\n <div ref={ref} className=\"map-manager-sublayer-tree-content\">\r\n {width && height ? <ControlledTree\r\n nodeLoader={nodeLoader}\r\n selectionMode={SelectionMode.None}\r\n eventsHandler={eventHandler}\r\n model={treeModel}\r\n treeRenderer={nodeWithEyeCheckboxTreeRenderer}\r\n nodeHighlightingProps={nodeHighlightingProps}\r\n width={width}\r\n height={height}\r\n /> : null}\r\n </div>\r\n </div>\r\n </>;\r\n}\r\n\r\n/** TreeEventHandler derived class that handler processing changes to subLayer visibility */\r\nclass SubLayerCheckboxHandler extends TreeEventHandler {\r\n private _removeModelChangedListener: () => void;\r\n\r\n constructor(private _mapLayer: StyleMapLayerSettings, nodeLoader: AbstractTreeNodeLoaderWithProvider<TreeDataProvider>) {\r\n super({ modelSource: nodeLoader.modelSource, nodeLoader, collapsedChildrenDisposalEnabled: true });\r\n this._removeModelChangedListener = this.modelSource.onModelChanged.addListener(this.onModelChanged);\r\n }\r\n\r\n public override dispose() {\r\n this._removeModelChangedListener();\r\n super.dispose();\r\n }\r\n\r\n // Cascade state\r\n // Children on unnamed groups must get disabled in the tree view, because\r\n // they get rendered anyway.\r\n private cascadeStateToAllChildren(model: MutableTreeModel, parentId?: string) {\r\n const children = model.getChildren(parentId);\r\n if (children === undefined)\r\n return;\r\n\r\n for (const childID of children) {\r\n const childNode = childID ? model.getNode(childID) : undefined;\r\n\r\n if (childNode)\r\n this.syncNodeStateWithParent(model, childNode);\r\n\r\n // Drill down the tree.\r\n this.cascadeStateToAllChildren(model, childID);\r\n }\r\n }\r\n\r\n private applyMutualExclusiveState(model: MutableTreeModel, nodeId: string) {\r\n const changedNode = model.getNode(nodeId);\r\n if (changedNode?.checkbox.state === CheckBoxState.Off)\r\n return;\r\n\r\n for (const node of model.iterateTreeModelNodes()) {\r\n if (node.id === changedNode?.id)\r\n continue;\r\n\r\n if (node && node.checkbox.state === CheckBoxState.On)\r\n node.checkbox.state = CheckBoxState.Off;\r\n }\r\n }\r\n\r\n //-----------------------------------------------------------------------\r\n // Listen to model changes\r\n //------------------------------------------------------------------------\r\n // This is required because nodes are delay loaded in the model until\r\n // they are made visible (i.e. parent node is expanded). So even though\r\n // you might have created nodes in the data provided with a proper\r\n // initial state, by the time it gets loaded, their state might have became\r\n // out of date in the TreeView's active model. So whenever a node\r\n // is added, when must confirm its state matches the current model\r\n // (i.e. state of their parent.)\r\n public onModelChanged = (args: [TreeModel, TreeModelChanges]) => {\r\n this.modelSource.modifyModel((model) => {\r\n const addedNodes = args[1].addedNodeIds.map((id) => model.getNode(id));\r\n addedNodes.forEach((node) => {\r\n if (!node)\r\n return;\r\n\r\n this.syncNodeStateWithParent(model, node);\r\n });\r\n });\r\n };\r\n\r\n private static isUnnamedGroup(subLayer: MapSubLayerProps | undefined): boolean {\r\n if (!subLayer)\r\n return false;\r\n\r\n return (!subLayer.name || subLayer.name.length === 0) && (subLayer.children !== undefined && subLayer.children.length > 0);\r\n }\r\n\r\n // Ensure the state of changed node matches the state of its parent.\r\n private syncNodeStateWithParent(model: MutableTreeModel, changedNode: MutableTreeModelNode) {\r\n // Lookup node parent. If non exists, I assume thats the root node,\r\n // and it must have a proper initial state.\r\n const parentNode = changedNode.parentId ? model.getNode(changedNode.parentId) : undefined;\r\n if (!parentNode)\r\n return;\r\n\r\n if (!changedNode.checkbox)\r\n return; // don't see why this would happen, but if there is no checkbox, we cant do much here.\r\n\r\n const parentLayerId = undefined !== parentNode.item.extendedData?.subLayerId ? parentNode.item.extendedData?.subLayerId : parentNode.item.id;\r\n const parentSubLayer = this._mapLayer.subLayers?.find((subLayer) => subLayer.id === parentLayerId);\r\n\r\n // If parent is disabled, then children must be too.\r\n // Also, Non-visible unnamed group must have their children disabled (unamed groups have visibility inherence)\r\n if (parentNode.checkbox.isDisabled || (SubLayerCheckboxHandler.isUnnamedGroup(parentSubLayer) && parentNode.checkbox.state === CheckBoxState.Off)) {\r\n changedNode.checkbox.isDisabled = true;\r\n changedNode.checkbox.state = CheckBoxState.Off;\r\n } else {\r\n // Visibility state from StyleMapLayerSettings applies\r\n const subLayerId = undefined !== changedNode.item.extendedData?.subLayerId ? changedNode.item.extendedData?.subLayerId : changedNode.item.id;\r\n const foundSubLayer = this._mapLayer.subLayers?.find((subLayer) => subLayer.id === subLayerId);\r\n changedNode.checkbox.isDisabled = false;\r\n changedNode.checkbox.state = foundSubLayer?.visible ? CheckBoxState.On : CheckBoxState.Off;\r\n }\r\n }\r\n\r\n /** Changes nodes checkboxes states until event is handled or handler is disposed */\r\n public override onCheckboxStateChanged({ stateChanges }: TreeCheckboxStateChangeEventArgs) {\r\n // call base checkbox handling\r\n const baseHandling = super.onCheckboxStateChanged({ stateChanges });\r\n\r\n // subscribe to checkbox state changes to new checkbox states and do some additional work with them\r\n const selectionHandling = stateChanges.subscribe({\r\n next: (changes) => {\r\n const vp = IModelApp.viewManager.selectedView;\r\n const displayStyle = vp?.displayStyle;\r\n const indexInDisplayStyle = displayStyle ? displayStyle.findMapLayerIndexByNameAndUrl(this._mapLayer.name, this._mapLayer.url, this._mapLayer.isOverlay) : -1;\r\n changes.forEach((change) => {\r\n const isSelected = (change.newState === CheckBoxState.On);\r\n\r\n const subLayerId = undefined !== change.nodeItem.extendedData?.subLayerId ? change.nodeItem.extendedData?.subLayerId : change.nodeItem.id;\r\n\r\n // Get the previously visible node if any\r\n let prevVisibleLayer: MapSubLayerProps | undefined;\r\n if (this._mapLayer.provider?.mutualExclusiveSubLayer) {\r\n prevVisibleLayer = this._mapLayer.subLayers?.find((subLayer) => subLayer.visible && subLayer.id !== subLayerId);\r\n }\r\n\r\n // Update sublayer object, otherwise state would get out of sync with DisplayStyle each time the TreeView is re-rendered\r\n const foundSubLayer = this._mapLayer.subLayers?.find((subLayer) => subLayer.id === subLayerId);\r\n if (foundSubLayer)\r\n foundSubLayer.visible = isSelected;\r\n if (prevVisibleLayer?.visible)\r\n prevVisibleLayer.visible = false;\r\n\r\n // Update displaystyle state\r\n if (-1 !== indexInDisplayStyle && displayStyle) {\r\n if (prevVisibleLayer && prevVisibleLayer.id !== undefined)\r\n displayStyle.changeMapSubLayerProps({ visible: false }, prevVisibleLayer.id, indexInDisplayStyle, this._mapLayer.isOverlay);\r\n displayStyle.changeMapSubLayerProps({ visible: isSelected }, subLayerId, indexInDisplayStyle, this._mapLayer.isOverlay);\r\n }\r\n\r\n // Cascade state\r\n this.modelSource.modifyModel((model) => {\r\n if (this._mapLayer.provider?.mutualExclusiveSubLayer)\r\n this.applyMutualExclusiveState(model, change.nodeItem.id);\r\n this.cascadeStateToAllChildren(model, change.nodeItem.id);\r\n });\r\n });\r\n\r\n if (vp)\r\n vp.invalidateRenderPlan();\r\n },\r\n });\r\n // stop handling selection when checkboxes handling is stopped\r\n baseHandling?.add(selectionHandling);\r\n return baseHandling;\r\n }\r\n}\r\n\r\n/** Custom checkbox renderer that renders checkbox as an eye */\r\nconst eyeCheckboxRenderer = (props: NodeCheckboxRenderProps) => (\r\n <ImageCheckBox\r\n checked={props.checked}\r\n disabled={props.disabled}\r\n imageOn=\"icon-visibility\"\r\n imageOff=\"icon-visibility-hide-2\"\r\n onClick={props.onChange}\r\n tooltip={props.title}\r\n />\r\n);\r\n\r\n/** Custom node renderer. It uses default 'TreeNodeRenderer' but overrides default checkbox renderer to render checkbox as an eye */\r\nconst imageLoader = new TreeImageLoader();\r\nconst nodeWithEyeCheckboxRenderer = (props: TreeNodeRendererProps) => (\r\n <TreeNodeRenderer\r\n {...props}\r\n checkboxRenderer={eyeCheckboxRenderer}\r\n imageLoader={imageLoader}\r\n />\r\n);\r\n\r\n/** Custom tree renderer. It uses default `TreeRenderer` but overrides default node renderer to render node with custom checkbox */\r\nconst nodeWithEyeCheckboxTreeRenderer = (props: TreeRendererProps) => (\r\n <TreeRenderer\r\n {...props}\r\n nodeRenderer={nodeWithEyeCheckboxRenderer}\r\n />\r\n);\r\n\r\nfunction useTreeFiltering(\r\n dataProvider: ITreeDataProvider,\r\n filter: string,\r\n) {\r\n const nodeLoader = useFilteredProvider(dataProvider, filter);\r\n const nodeHighlightingProps = useNodeHighlightingProps(filter);\r\n return {\r\n nodeLoader,\r\n modelSource: nodeLoader.modelSource,\r\n nodeHighlightingProps,\r\n };\r\n}\r\n\r\nfunction useFilteredProvider(\r\n dataProvider: ITreeDataProvider,\r\n filter: string,\r\n) {\r\n const filteredProvider = React.useMemo(() => {\r\n return new FilteredTreeDataProvider(dataProvider, filter);\r\n }, [dataProvider, filter]);\r\n\r\n const nodeLoader = React.useMemo(() => {\r\n return new TreeNodeLoader(filteredProvider, new TreeModelSource());\r\n }, [filteredProvider]);\r\n\r\n return nodeLoader;\r\n}\r\n\r\nfunction useNodeHighlightingProps(\r\n filter: string,\r\n) {\r\n const [nodeHighlightingProps, setNodeHighlightingProps] = React.useState<HighlightableTreeProps>();\r\n\r\n React.useEffect(() => {\r\n if (filter === \"\") {\r\n setNodeHighlightingProps(undefined);\r\n return;\r\n }\r\n setNodeHighlightingProps({\r\n searchText: filter,\r\n activeMatch: undefined,\r\n });\r\n }, [filter]);\r\n\r\n return nodeHighlightingProps;\r\n}\r\n\r\nclass FullTreeHierarchy {\r\n private _dataProvider: ITreeDataProvider;\r\n private _hierarchy = new Map<string | undefined, DelayLoadedTreeNodeItem[]>();\r\n private _init: Promise<void>;\r\n\r\n public constructor(dataProvider: ITreeDataProvider) {\r\n this._dataProvider = dataProvider;\r\n\r\n this._init = (async () => {\r\n await this.initNode();\r\n })();\r\n }\r\n\r\n private async initNode(parent?: TreeNodeItem) {\r\n const nodes = await this._dataProvider.getNodes(parent);\r\n this._hierarchy.set(parent?.id, nodes);\r\n for (const node of nodes) {\r\n await this.initNode(node);\r\n }\r\n }\r\n\r\n public async getHierarchy() {\r\n await this._init;\r\n return this._hierarchy;\r\n }\r\n}\r\n\r\nclass FilteredTreeHierarchy {\r\n private _fullHierarchy: FullTreeHierarchy;\r\n private _filter: string;\r\n private _filtered = new Map<string | undefined, DelayLoadedTreeNodeItem[]>();\r\n private _init: Promise<void>;\r\n\r\n public constructor(dataProvider: ITreeDataProvider, filter: string) {\r\n this._fullHierarchy = new FullTreeHierarchy(dataProvider);\r\n this._filter = filter;\r\n\r\n this._init = (async () => {\r\n await this.init();\r\n })();\r\n }\r\n\r\n private async init() {\r\n const hierarchy = await this._fullHierarchy.getHierarchy();\r\n if (this._filter === \"\") {\r\n this._filtered = hierarchy;\r\n return;\r\n }\r\n this.filterNodes(hierarchy);\r\n }\r\n\r\n /** Initializes `this._filtered` field. Returns a node if it matches a filter. */\r\n private filterNodes(hierarchy: Map<string | undefined, DelayLoadedTreeNodeItem[]>, current?: DelayLoadedTreeNodeItem): DelayLoadedTreeNodeItem | undefined {\r\n const matches = current ? this.matchesFilter(current) : false;\r\n const children = hierarchy.get(current?.id);\r\n if (!children)\r\n return matches ? current : undefined;\r\n\r\n const matchedChildren = new Array<DelayLoadedTreeNodeItem>();\r\n for (const child of children) {\r\n const matchedChild = this.filterNodes(hierarchy, child);\r\n matchedChild && matchedChildren.push(matchedChild);\r\n }\r\n\r\n const hasChildren = matchedChildren.length > 0;\r\n const included = matches || hasChildren;\r\n let filtered: DelayLoadedTreeNodeItem | undefined;\r\n if (included) {\r\n this._filtered.set(current?.id, matchedChildren);\r\n\r\n // Return a modified copy of current node (to persist initial hierarchy when filter is cleared).\r\n if (current) {\r\n filtered = {\r\n ...current,\r\n hasChildren,\r\n autoExpand: hasChildren ? true : current.autoExpand,\r\n };\r\n }\r\n }\r\n return filtered;\r\n }\r\n\r\n private matchesFilter(node: TreeNodeItem) {\r\n if (node.label.value.valueFormat !== PropertyValueFormat.Primitive)\r\n return false;\r\n\r\n const value = node.label.value.displayValue?.toLowerCase();\r\n if (!value)\r\n return false;\r\n return value.includes(this._filter.toLowerCase());\r\n }\r\n\r\n public async getHierarchy() {\r\n await this._init;\r\n return this._filtered;\r\n }\r\n}\r\n\r\nclass FilteredTreeDataProvider implements ITreeDataProvider {\r\n private _hierarchy: FilteredTreeHierarchy;\r\n\r\n public constructor(\r\n parentDataProvider: ITreeDataProvider,\r\n filter: string,\r\n ) {\r\n this._hierarchy = new FilteredTreeHierarchy(parentDataProvider, filter);\r\n }\r\n\r\n public async getNodes(parent?: TreeNodeItem) {\r\n const hierarchy = await this._hierarchy.getHierarchy();\r\n const nodes = hierarchy.get(parent?.id);\r\n return nodes || [];\r\n }\r\n\r\n public async getNodesCount(parent?: TreeNodeItem) {\r\n const hierarchy = await this._hierarchy.getHierarchy();\r\n const nodes = hierarchy.get(parent?.id);\r\n return nodes?.length || 0;\r\n }\r\n}\r\n"]}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/*---------------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
3
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
@import "~@itwin/core-react/lib/cjs/core-react/index";
|
|
6
|
+
|
|
7
|
+
.map-manager-sublayer-tree {
|
|
8
|
+
height: 100%;
|
|
9
|
+
width: 100%;
|
|
10
|
+
display: flex;
|
|
11
|
+
flex-direction: column;
|
|
12
|
+
|
|
13
|
+
.core-tree-node {
|
|
14
|
+
>.contents {
|
|
15
|
+
padding-left: 31px;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.core-image-checkbox {
|
|
20
|
+
position: absolute;
|
|
21
|
+
left: 5px;
|
|
22
|
+
padding: 0;
|
|
23
|
+
margin: -2px 0px 0px 5px;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.map-manager-sublayer-tree-toolbar {
|
|
28
|
+
display: flex;
|
|
29
|
+
flex-direction: row;
|
|
30
|
+
margin: 0 4px 6px 0;
|
|
31
|
+
|
|
32
|
+
.tree-toolbar-action-buttons {
|
|
33
|
+
display: flex;
|
|
34
|
+
flex-direction: row;
|
|
35
|
+
flex-wrap: nowrap;
|
|
36
|
+
|
|
37
|
+
button {
|
|
38
|
+
height: 32px;
|
|
39
|
+
width: 32px;
|
|
40
|
+
background-color: transparent;
|
|
41
|
+
color: var(--buic-foreground-body);
|
|
42
|
+
border: 1px solid var(--buic-background-toolbutton-stroke);
|
|
43
|
+
|
|
44
|
+
&:hover {
|
|
45
|
+
color: var(--buic-accessory-primary-tint);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
&:focus {
|
|
49
|
+
box-shadow: $uicore-button-focus-boxshadow;
|
|
50
|
+
outline: none;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.tree-toolbar-searchbox {
|
|
56
|
+
margin-left: 6px;
|
|
57
|
+
width: 100%;
|
|
58
|
+
;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.map-manager-sublayer-tree-content {
|
|
63
|
+
flex-grow: 1;
|
|
64
|
+
}
|