import * as React from "react";
import {
ViewMode,
DrawPointMode,
DrawLineStringMode,
DrawPolygonMode,
DrawCircleFromCenterMode,
DrawRectangleMode,
MeasureDistanceMode,
MeasureAngleMode,
MeasureAreaMode,
ModifyMode,
TranslateMode
} from "@nebula.gl/edit-modes";
import styled from "styled-components";
import { Icon } from "./icon";
import { ImportModal } from "./import-modal";
import { ExportModal } from "./export-modal";
const Tools = styled.div`
position: absolute;
display: flex;
flex-direction: column;
top: 40px;
left: 10px;
`;
const Button = styled.button<{ active?: boolean; kind?: string }>`
color: #fff;
background: ${({ kind, active }) => (kind === "danger" ? "rgb(180, 40, 40)" : active ? "rgb(56, 111, 164)" : "rgb(69, 102, 131)")};
font-size: 1em;
font-weight: 400;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji",
"Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
border: 1px solid transparent;
border-radius: 0.25em;
margin: 0.05em;
padding: 0.1em 0.2em;
:hover {
background: rgb(56, 111, 164);
}
`;
const SubToolsContainer = styled.div`
position: relative;
`;
const SubTools = styled.div`
display: flex;
flex-direction: row-reverse;
position: absolute;
top: 0;
left: 0;
`;
export interface ToolboxOptions {
viewModeEnabled?: boolean,
drawPointModeEnabled?: boolean,
drawLineModeEnabled?: boolean,
drawPolygonModeEnabled?: boolean,
drawRectangleModeEnabled?: boolean,
drawCircleModeEnabled?: boolean,
measureDistanceModeEnabled?: boolean,
measureAngleModeEnabled?: boolean,
measureAreaModeEnabled?: boolean,
editModeEnabled?: boolean,
moveModeEnabled?: boolean,
importEnabled?: boolean,
exportEnabled?: boolean,
settingsModeEnabled?: boolean, // not implemented/tested yet
deleteEnabled?: boolean,
}
export type Props = {
mode: any;
modeConfig: any;
geoJson: any;
onSetMode: (mode: any) => unknown;
onSetModeConfig: (modeConfig: any) => unknown;
onSetGeoJson: (geojson: any) => unknown;
onImport: (imported: any) => unknown;
options?: ToolboxOptions,
};
const defaultToolBoxOptions: ToolboxOptions = {
viewModeEnabled: true,
drawPointModeEnabled: true,
drawLineModeEnabled: true,
drawPolygonModeEnabled: true,
drawRectangleModeEnabled: true,
drawCircleModeEnabled: true,
measureDistanceModeEnabled: true,
measureAngleModeEnabled: true,
measureAreaModeEnabled: true,
editModeEnabled: true,
moveModeEnabled: true,
importEnabled: true,
exportEnabled: true,
settingsModeEnabled: false,
deleteEnabled: true
}
const MODE_GROUPS = [
{
modes: [{ mode: ViewMode, content: , id: 'viewMode' }]
},
{
modes: [{ mode: DrawPointMode, content: , id: 'drawPointMode', }]
},
{
modes: [
{
mode: DrawLineStringMode,
content: ,
id: 'drawLineMode'
}
]
},
{
modes: [
{ mode: DrawPolygonMode, content: , id: 'drawPolygonMode' },
{ mode: DrawRectangleMode, content: , id: 'drawRectangleMode' },
{ mode: DrawCircleFromCenterMode, content: , id: 'drawCircleMode' }
]
},
{
modes: [
{ mode: MeasureDistanceMode, content: , id: 'measureDistanceMode' },
{ mode: MeasureAngleMode, content: , id: 'measureAngleMode' },
{ mode: MeasureAreaMode, content: , id: 'measureAreaMode' }
]
},
{
modes: [{ mode: ModifyMode, content: , id: 'editMode' }]
},
{
modes: [{ mode: TranslateMode, content: , id: 'moveMode' }]
}
];
const isButtonEnabled = (id:string, options: ToolboxOptions) => !!Object.keys(options).find(key => `${id}Enabled` === key && options[key])
function ModeButton({ buttonConfig, mode, onClick }: any) {
return (
);
}
function ModeGroupButtons({ modeGroup, mode, onSetMode, options }: any) {
const useOptions: ToolboxOptions = options;
const [expanded, setExpanded] = React.useState(false);
const { modes } = modeGroup;
const mayShowMainButton = !!modes.find(m => isButtonEnabled(m.id, useOptions));
if(!mayShowMainButton){
return null;
}
let subTools = null;
if (expanded) {
subTools = (
{modes.map((buttonConfig, i) => {
const mayShowCurrentButton = isButtonEnabled(buttonConfig.id, useOptions);
if(!mayShowCurrentButton) return true;
return {
onSetMode(() => buttonConfig.mode);
setExpanded(false);
}}
/>
})}
);
}
// Get the button config if it is active otherwise, choose the first valid one that can be shown
const buttonConfig = modes.find(m => m.mode === mode) || modes.find(m => isButtonEnabled(m.id, useOptions));
return (
{subTools}
{
onSetMode(() => buttonConfig.mode);
setExpanded(true);
}}
/>
);
}
export function Toolbox({
mode,
modeConfig,
geoJson,
onSetMode,
onSetModeConfig,
onSetGeoJson,
onImport,
options
}: Props) {
const [showConfig, setShowConfig] = React.useState(false);
const [showImport, setShowImport] = React.useState(false);
const [showExport, setShowExport] = React.useState(false);
const [showClearConfirmation, setShowClearConfirmation] = React.useState(false);
const useOptions = { ...defaultToolBoxOptions, ...(options || {}) };
const { settingsModeEnabled, importEnabled, exportEnabled, deleteEnabled } = useOptions;
return (
<>
{MODE_GROUPS.map((modeGroup, i) => (
))}
{/* */}
{exportEnabled && }
{importEnabled && }
{settingsModeEnabled && (
{showConfig && (
{/* */}
)}
)}
{deleteEnabled &&
{showClearConfirmation && (
)}
}
{/* zoom in and out */}
{showImport && (
{
onImport(imported);
setShowImport(false);
}}
onClose={() => setShowImport(false)}
/>
)}
{showExport && setShowExport(false)} />}
>
);
}