@itwin/measure-tools-react
Version:
Frontend framework and tools for measurements
113 lines • 6.44 kB
JavaScript
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
import { MeasurementSyncUiEventId } from "./MeasurementEnums.js";
import { BeUiEvent } from "@itwin/core-bentley";
import { DistanceMeasurement } from "../measurements/DistanceMeasurement.js";
import { SyncUiEventDispatcher } from "@itwin/appui-react";
import { ShimFunctions } from "./ShimFunctions.js";
/** UI events for measurements. Maintains app state of each event type, so events only trigger when the state actually changes. */
export class MeasurementUIEvents {
/** Gets or sets the User-defined handler to override default behavior of determining whether a measurement should be cleared. By default
* the UI button is visible if there exists at least one non-locked measurement.
*/
static get shouldClearMeasurementHandler() {
return MeasurementUIEvents._shouldClearMeasurementHandler;
}
static set shouldClearMeasurementHandler(handler) {
MeasurementUIEvents._shouldClearMeasurementHandler = handler;
}
/**
* Gets or sets the User-defined handler to override default behavior of determining whether a measurement is counted towards showing
* the "Toggle Measurement Axes" button. By default the UI button is visible if there exists at least one Distance Measurement.
*/
static get showToggleMeasurementAxesHandler() {
return MeasurementUIEvents._showToggleMeaurementAxesHandler;
}
static set showToggleMeasurementAxesHandler(handler) {
MeasurementUIEvents._showToggleMeaurementAxesHandler = handler;
}
/** Get the visibility state of the "Clear Measurements" button */
static get isClearMeasurementButtonVisible() {
return this._clearMeasurementState;
}
/** Get the visibility state of the "Toggle Measurement Axes" button */
static get isToggleMeasurementAxesButtonVisible() {
return this._toggleMeasurementAxestate;
}
/**
* Notify listeners who need to refresh if measurement properties have changed. E.g. measurement property grid.
* @param measurements Measurements whose properties have changed.
*/
static notifyMeasurementPropertiesChanged(measurements) {
MeasurementUIEvents.onMeasurementPropertiesChanged.emit(measurements);
SyncUiEventDispatcher.dispatchSyncUiEvent(MeasurementSyncUiEventId.MeasurementSelectionSetChanged);
}
/** Notify a change in measurements. If you implement a new measurement creation tool, you should call this if you make changes to it's measurement state (the measurement decorator already does this).
*/
static notifyMeasurementsChanged() {
MeasurementUIEvents.onMeasurementsChanged.emit();
MeasurementUIEvents.determineClearMeasurementStateChange();
MeasurementUIEvents.determineToggleMeasurementAxesStateChange();
}
static determineClearMeasurementStateChange() {
const prevState = MeasurementUIEvents._clearMeasurementState;
const currentState = MeasurementUIEvents.queryActiveMeasurementCount() > 0;
if (currentState !== prevState) {
MeasurementUIEvents._clearMeasurementState = currentState;
MeasurementUIEvents.onClearMeasurementButtonVisibilityChanged.emit(currentState);
}
}
static determineToggleMeasurementAxesStateChange() {
const overrideHandler = MeasurementUIEvents._showToggleMeaurementAxesHandler;
const prevState = MeasurementUIEvents._toggleMeasurementAxestate;
const result = { currentState: false };
// Determine if the show axes button needs to be shown. App may provide handler to provide custom logic.
ShimFunctions.forAllMeasurements((overrideHandler) ? (measurement) => {
if (overrideHandler(measurement)) {
result.currentState = true;
return false;
}
return true;
} : (measurement) => {
if (measurement instanceof DistanceMeasurement) {
result.currentState = true;
return false;
}
return true;
});
if (result.currentState !== prevState) {
MeasurementUIEvents._toggleMeasurementAxestate = result.currentState;
MeasurementUIEvents.onToggleMeasurementAxesButtonVisibilityChanged.emit(result.currentState);
}
}
static queryActiveMeasurementCount() {
const overrideClearHandler = MeasurementUIEvents._shouldClearMeasurementHandler;
const result = { count: 0 };
// Get all the non-locked measurements (by default), app may provide a handler that determines what exactly constitutes an active measurement though
ShimFunctions.forAllMeasurements((overrideClearHandler) ? (measurement) => {
if (overrideClearHandler(measurement))
result.count++;
return true;
} : (measurement) => {
if (!measurement.isLocked) {
result.count++;
}
return true;
});
return result.count;
}
}
MeasurementUIEvents._clearMeasurementState = false; // Default is false, only want the button to show if have measurements
MeasurementUIEvents._shouldClearMeasurementHandler = undefined;
MeasurementUIEvents._toggleMeasurementAxestate = false; // Defalt is false, only want the button to show if have measurements that have axes
/** Occurs when the visibility state of the "Clear Measurements" button changes */
MeasurementUIEvents.onClearMeasurementButtonVisibilityChanged = new BeUiEvent();
/** Occurs when the visibility state of the "Toggle Measurement Axes" button changes */
MeasurementUIEvents.onToggleMeasurementAxesButtonVisibilityChanged = new BeUiEvent();
/** Occurs whenever notifyMeasurementsChanged() is called. Query the measurement manager or active measurement tool for changes. */
MeasurementUIEvents.onMeasurementsChanged = new BeUiEvent();
/** Notify UI (e.g. property grid) if the following measurements have modified and need to refresh the UI. */
MeasurementUIEvents.onMeasurementPropertiesChanged = new BeUiEvent();
//# sourceMappingURL=MeasurementUIEvents.js.map