UNPKG

@acransac/vtk.js

Version:

Visualization Toolkit for the Web

164 lines (139 loc) 5.32 kB
import macro from 'vtk.js/Sources/macro'; import vtkPointPicker from 'vtk.js/Sources/Rendering/Core/PointPicker'; const MAX_POINTS = 3; export default function widgetBehavior(publicAPI, model) { model.classHierarchy.push('vtkAngleWidgetProp'); let isDragging = null; const picker = vtkPointPicker.newInstance(); picker.setPickFromList(1); // -------------------------------------------------------------------------- // Display 2D // -------------------------------------------------------------------------- publicAPI.setDisplayCallback = (callback) => model.representations[0].setDisplayCallback(callback); // -------------------------------------------------------------------------- // Interactor events // -------------------------------------------------------------------------- function ignoreKey(e) { return e.altKey || e.controlKey || e.shiftKey; } // -------------------------------------------------------------------------- // Left press: Select handle to drag // -------------------------------------------------------------------------- publicAPI.handleLeftButtonPress = (e) => { if ( !model.activeState || !model.activeState.getActive() || !model.pickable || ignoreKey(e) ) { return macro.VOID; } picker.initializePickList(); picker.setPickList(publicAPI.getNestedProps()); if ( model.activeState === model.widgetState.getMoveHandle() && model.widgetState.getHandleList().length < MAX_POINTS ) { // Commit handle to location const moveHandle = model.widgetState.getMoveHandle(); const newHandle = model.widgetState.addHandle(); newHandle.setOrigin(...moveHandle.getOrigin()); newHandle.setColor(moveHandle.getColor()); newHandle.setScale1(moveHandle.getScale1()); } else { isDragging = true; model.openGLRenderWindow.setCursor('grabbing'); model.interactor.requestAnimation(publicAPI); } publicAPI.invokeStartInteractionEvent(); return macro.EVENT_ABORT; }; // -------------------------------------------------------------------------- // Mouse move: Drag selected handle / Handle follow the mouse // -------------------------------------------------------------------------- publicAPI.handleMouseMove = (callData) => { if ( model.pickable && model.manipulator && model.activeState && model.activeState.getActive() && !ignoreKey(callData) ) { model.manipulator.setOrigin(model.activeState.getOrigin()); model.manipulator.setNormal(model.camera.getDirectionOfProjection()); const worldCoords = model.manipulator.handleEvent( callData, model.openGLRenderWindow ); if ( worldCoords.length && (model.activeState === model.widgetState.getMoveHandle() || isDragging) ) { model.activeState.setOrigin(worldCoords); publicAPI.invokeInteractionEvent(); return macro.EVENT_ABORT; } } if (model.hasFocus) { model.widgetManager.disablePicking(); } return macro.VOID; }; // -------------------------------------------------------------------------- // Left release: Finish drag / Create new handle // -------------------------------------------------------------------------- publicAPI.handleLeftButtonRelease = () => { if (isDragging && model.pickable) { model.openGLRenderWindow.setCursor('pointer'); model.widgetState.deactivate(); model.interactor.cancelAnimation(publicAPI); publicAPI.invokeEndInteractionEvent(); } else if (model.activeState !== model.widgetState.getMoveHandle()) { model.widgetState.deactivate(); } if ( (model.hasFocus && !model.activeState) || (model.activeState && !model.activeState.getActive()) ) { publicAPI.invokeEndInteractionEvent(); model.widgetManager.enablePicking(); model.interactor.render(); } // Don't make any more points if (model.widgetState.getHandleList().length === MAX_POINTS) { publicAPI.loseFocus(); } isDragging = false; }; // -------------------------------------------------------------------------- // Focus API - modeHandle follow mouse when widget has focus // -------------------------------------------------------------------------- publicAPI.grabFocus = () => { if ( !model.hasFocus && model.widgetState.getHandleList().length < MAX_POINTS ) { model.activeState = model.widgetState.getMoveHandle(); model.activeState.activate(); model.activeState.setVisible(true); model.interactor.requestAnimation(publicAPI); publicAPI.invokeStartInteractionEvent(); } model.hasFocus = true; }; // -------------------------------------------------------------------------- publicAPI.loseFocus = () => { if (model.hasFocus) { model.interactor.cancelAnimation(publicAPI); publicAPI.invokeEndInteractionEvent(); } model.widgetState.deactivate(); model.widgetState.getMoveHandle().deactivate(); model.widgetState.getMoveHandle().setVisible(false); model.activeState = null; model.hasFocus = false; model.widgetManager.enablePicking(); model.interactor.render(); }; }