terriajs
Version:
Geospatial data visualization platform.
167 lines • 5.84 kB
JavaScript
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import { action, computed, makeObservable } from "mobx";
import createGuid from "terriajs-cesium/Source/Core/createGuid";
import TerriaError from "../../Core/TerriaError";
import MapNavigationItemController from "./MapNavigationItemController";
export { default as ViewerMode } from "../../Models/ViewerMode";
/**
* Adds a new tool to the map toolbar
*
* @param viewState The {@link ViewState} instance
* @param config The tool configuration
* @returns `id` of the tool. This will be the same as `config.id` if it was set. Otherwise, a random `id` is generated and returned.
*
* Example:
* const toolId = addTool(viewState, {
* name: "X Tool",
* toolComponentLoader: () => import("./XTool.tsx"),
* toolButton: {
* text: "Open X tool",
* tooltip: "X Tool",
* icon: X_ICON
* }
* })
*/
export function addTool(viewState, config) {
const id = config.id ?? createGuid();
const controller = new ToolController(viewState, id, config);
const terria = viewState.terria;
terria.mapNavigationModel.addItem({
id,
name: config.toolButton.text,
title: config.toolButton.tooltip,
location: config.toolButton.section ?? "TOP",
order: config.toolButton.order,
controller
});
return id;
}
/**
* Function to programatically open the tool with given ID.
*
* Note that in normal operation, a tool will be opened when user clicks the
* tool button in the map toolbar. This function is useful in situations where
* the tool needs to be opened through other means - like clicking a workbench
* viewing-controls button.
*
* If no tool exists with the given `toolId` then this function does nothing
* and returns `false`. The caller can also check if the call was successful
* by checking the result of {@link isToolOpen()}.
*
* @param viewState The `ViewState` instance.
* @param toolId ID of the tool to open. See {@link addTool}.
* @param props Optional props to pass to the Tool component when activating it.
* @returns `true` if the tool was successfully opened.
*/
export function openTool(viewState, toolId, props) {
const controller = findToolController(viewState, toolId);
controller?.openTool(props);
return controller?.isToolOpen === true;
}
/**
* Closes the tool with given id.
*
* @param viewState The `ViewState` instance.
* @param toolId ID of the tool to close.
*/
export function closeTool(viewState, toolId) {
findToolController(viewState, toolId)?.closeTool();
}
/**
* Check if tool with given `id` is currently open.
*
* @param viewState The `ViewState` instance.
* @param toolId ID of the tool to check.
* @returns `true` if the tool is currently open, otherwise returns `false`.
*/
export function isToolOpen(viewState, toolId) {
return findToolController(viewState, toolId)?.active === true;
}
/**
* Removes the tool with the given id from the toolbar.
*
* @param viewState The `ViewState` instance.
* @param toolId ID of the tool to close.
*/
export function removeTool(viewState, toolId) {
viewState.terria.mapNavigationModel.remove(toolId);
}
/**
* Find `ToolController` by id.
*/
function findToolController(viewState, toolId) {
const navItem = viewState.terria.mapNavigationModel.items.find((it) => it.id === toolId);
return navItem?.controller instanceof ToolController
? navItem.controller
: undefined;
}
export class ToolController extends MapNavigationItemController {
viewState;
toolId;
toolConfig;
constructor(viewState, toolId, toolConfig) {
super();
this.viewState = viewState;
this.toolId = toolId;
this.toolConfig = toolConfig;
makeObservable(this);
}
get glyph() {
return this.toolConfig.toolButton.icon;
}
get viewerMode() {
return this.toolConfig.viewerMode;
}
get isToolOpen() {
return this.viewState.currentTool?.toolName === this.toolConfig.name;
}
get active() {
return super.active && this.isToolOpen;
}
openTool(props = {}) {
const toolConfig = this.toolConfig;
const toolId = this.toolId;
try {
this.viewState.openTool({
toolName: toolConfig.name,
getToolComponent: () => toolConfig.toolComponentLoader().then((m) => m.default),
params: {
...props,
// Pass toolId as an extra prop to the component.
// TODO: Maybe we should use react contexts to do this instead of a magic prop?
toolId
}
});
}
catch (err) {
this.viewState.terria.raiseErrorToUser(TerriaError.from(err));
}
super.activate();
}
activate() {
this.openTool();
}
deactivate() {
this.closeTool();
}
closeTool() {
if (this.isToolOpen)
this.viewState.closeTool();
super.deactivate();
}
}
__decorate([
computed
], ToolController.prototype, "isToolOpen", null);
__decorate([
computed
], ToolController.prototype, "active", null);
__decorate([
action
], ToolController.prototype, "closeTool", null);
//# sourceMappingURL=MapToolbar.js.map