@itwin/core-frontend
Version:
iTwin.js frontend components
144 lines • 9.01 kB
TypeScript
/** @packageDocumentation
* @module Tools
*/
import { Point3d, Transform, Vector3d } from "@itwin/core-geometry";
import { ColorDef } from "@itwin/core-common";
import { HitDetail } from "../HitDetail";
import { IModelConnection } from "../IModelConnection";
import { SelectionSetEvent } from "../SelectionSet";
import { DecorateContext } from "../ViewContext";
import { Viewport } from "../Viewport";
import { BeButtonEvent, BeTouchEvent, EventHandled, InputCollector, Tool } from "./Tool";
import { ManipulatorToolEvent } from "./ToolAdmin";
/** Classes and methods to create on screen control handles for interactive modification of element(s) and pickable decorations.
* The basic flow is:
* - Create a sub-class of [[EditManipulator.HandleProvider]] to listen for start of [[SelectTool]] or any other PrimitiveTool that supports handle providers.
* - Respond to [[ManipulatorToolEvent.Start]] by adding a listener for [[SelectionSet]] change event.
* - Respond to selection changed event to create control handles as pickable decorations when the desired element(s) or pickable decoration is selected.
* - Respond to button events on the control handle decoration and run a sub-class of [[EditManipulator.HandleTool]] to modify.
* @public
* @extensions
*/
export declare namespace EditManipulator {
/** Specifies the event for [[EditManipulator.HandleProvider.onManipulatorEvent]] */
enum EventType {
/** Control handles should be created, updated, or cleared based on the active selection. */
Synch = 0,
/** Control handle modification was cancelled by user. */
Cancel = 1,
/** Control handle modification was accepted by user. */
Accept = 2
}
/** Interactive control handle modification is done by installing an [[InputCollector]].
* Modification typically is started from a click or press and drag while over the handle graphics.
* The HandleTool base class is set up to define an offset by 2 points. The second point is
* defined by either another click, or up event when initiated from press and drag.
* @see [[EditManipulator.HandleProvider]]
*/
abstract class HandleTool extends InputCollector {
static toolId: string;
static hidden: boolean;
readonly manipulator: HandleProvider;
constructor(manipulator: HandleProvider);
/** Establish the initial tool state for handle modification.
* Default implementation honors the active locks and enables AccuSnap; behavior suitable for a shape vertex handle.
* @note An InputCollector inherits the tool state of the suspended primitive tool.
*/
protected init(): void;
/** Whether to call [[AccuSnap.enableSnap]] for handle modification.
* @return true to enable snapping to elements.
*/
protected get wantAccuSnap(): boolean;
/** Called from reset button up event to allow modification to be cancelled.
* @return true to cancel modification.
*/
protected cancel(_ev: BeButtonEvent): boolean;
/** Called from data button down event to check if enough input has been gathered to complete the modification.
* @return true to complete modification.
*/
protected abstract accept(_ev: BeButtonEvent): boolean;
/** Called following cancel or accept to update the handle provider
* and return control to suspended PrimitiveTool.
*/
protected onComplete(_ev: BeButtonEvent, event: EventType): Promise<EventHandled>;
onDataButtonDown(ev: BeButtonEvent): Promise<EventHandled>;
onResetButtonUp(ev: BeButtonEvent): Promise<EventHandled>;
onTouchMove(ev: BeTouchEvent): Promise<void>;
onTouchComplete(ev: BeTouchEvent): Promise<void>;
onTouchCancel(ev: BeTouchEvent): Promise<void>;
onPostInstall(): Promise<void>;
}
/** A handle provider maintains a set of controls used to modify element(s) or pickable decorations.
* The provider works in conjunction with any PrimitiveTool that raises events for [[ToolAdmin.manipulatorToolEvent]].
* @see [[SelectTool]] The default PrimitiveTool that supports handle providers.
*/
abstract class HandleProvider {
iModel: IModelConnection;
protected _isActive: boolean;
protected _removeManipulatorToolListener?: () => void;
protected _removeSelectionListener?: () => void;
protected _removeDecorationListener?: () => void;
/** Create a new handle provider to listen for [[ToolAdmin.manipulatorToolEvent]].
* Usually followed by a call to [[IModelApp.toolAdmin.startDefaultTool]] to immediately raise the [[ManipulatorToolEvent.Start]] event.
*/
constructor(iModel: IModelConnection);
/** Call to clear this handle provider. */
protected stop(): void;
/** Event raised by a PrimitiveTool that supports handle providers.
* Add listener for [[IModelConnection.selectionSet.onChanged]] on start event and remove on stop event.
* Control handles can be created from the active selection set, which may include persistent elements and pickable decorations.
* @see [[SelectionSet]]
*/
onManipulatorToolEvent(_tool: Tool, event: ManipulatorToolEvent): void;
/** Event raised by [[SelectionSet]] when the active selection changes.
* Calls onManipulatorEvent to let the provider create, update, or clear it's set of controls as appropriate.
* @see [[SelectionSet]]
*/
onSelectionChanged(ev: SelectionSetEvent): void;
/** Register for decorate event to start displaying control handles. */
protected updateDecorationListener(add: boolean): void;
/** Sub-classes should override to display the pickable graphics for their controls. */
decorate(_context: DecorateContext): void;
/** The provider is responsible for checking if modification by controls is valid.
* May still wish to present controls for "transient" geometry in non-read/write applications, etc.
*/
protected abstract createControls(): Promise<boolean>;
protected clearControls(): void;
/** A provider can install an [[InputCollector]] to support interactive modification.
* @return true if a tool was successfully run.
* @see [[EditManipulator.HandleTool]]
*/
protected abstract modifyControls(_hit: HitDetail, _ev: BeButtonEvent): Promise<boolean>;
protected updateControls(): Promise<void>;
onManipulatorEvent(_eventType: EventType): void;
/** Sub-classes can override to perform some operation for a double click on a handle. */
protected onDoubleClick(_hit: HitDetail, _ev: BeButtonEvent): Promise<EventHandled>;
/** Sub-classes can override to present a menu for a right click on a handle. */
protected onRightClick(_hit: HitDetail, _ev: BeButtonEvent): Promise<EventHandled>;
/** Sub-classes can override to respond to a touch tap on a handle. By default, handles are selected by touch drag and taps are ignored. */
protected onTouchTap(_hit: HitDetail, _ev: BeButtonEvent): Promise<EventHandled>;
/** Event raised by a PrimitiveTool that supports handle providers to allow a pickable decoration to respond to being located. */
onDecorationButtonEvent(hit: HitDetail, ev: BeButtonEvent): Promise<EventHandled>;
}
/** Utility methods for creating control handles and other decorations. */
class HandleUtils {
/** Adjust input color for contrast against view background.
* @param color The color to adjust.
* @param vp The viewport to compare.
* @return color adjusted for view background color or original color if view background color isn't being used.
*/
static adjustForBackgroundColor(color: ColorDef, vp: Viewport): ColorDef;
/** Compute a transform that will try to orient a 2d shape (like an arrow) to face the camera.
* @param vp The viewport to get the rotation from.
* @param base The world coordinate point to pivot about.
* @param direction The world coordinate axis to tilt along.
* @param sizeInches The transform scale specified in screen inches.
* @returns transform or undefined when input direction is almost perpendicular to viewing direction.
* @see [[getArrowShape]]
*/
static getArrowTransform(vp: Viewport, base: Point3d, direction: Vector3d, sizeInches: number): Transform | undefined;
/** Return array of shape points representing a unit arrow in xy plane pointing in positive x direction. */
static getArrowShape(baseStart?: number, baseWidth?: number, tipStart?: number, tipEnd?: number, tipWidth?: number, flangeStart?: number, flangeWidth?: number): Point3d[];
}
}
//# sourceMappingURL=EditManipulator.d.ts.map