SeedWidget

Methods

Source

behavior.js
import macro from 'vtk.js/Sources/macros';

export default function widgetBehavior(publicAPI, model) {
model.classHierarchy.push('SeedWidgetProp');

const moveHandle = model.widgetState.getMoveHandle();
moveHandle.setVisible(true);
model._isDragging = false;
model.previousPosition = null;

function isValidHandle(handle) {
return handle === moveHandle;
}

function isPlaced() {
return !!moveHandle.getOrigin();
}

function currentWorldCoords(e) {
const manipulator =
model.activeState?.getManipulator?.() ?? model.manipulator;
return manipulator.handleEvent(e, model._apiSpecificRenderWindow)
.worldCoords;
}

// Update the handle's center. Example:
// handle.setCenter([1,2,3]);
publicAPI.setCenter = (newCenter) => {
moveHandle.setOrigin(newCenter);
model._widgetManager.enablePicking();
};

publicAPI.handleLeftButtonPress = (e) => {
if (!isValidHandle(model.activeState)) {
model.activeState = null;
return macro.VOID;
}
const worldCoords = currentWorldCoords(e);

if (model.activeState === moveHandle) {
if (!moveHandle.getOrigin() && worldCoords) {
moveHandle.setOrigin(worldCoords);
model.previousPosition = [...worldCoords];
}
}
model._isDragging = true;
model._apiSpecificRenderWindow.setCursor('grabbing');
publicAPI.invokeStartInteractionEvent();
return macro.EVENT_ABORT;
};

publicAPI.handleLeftButtonRelease = (e) => {
if (!model._isDragging) {
model.activeState = null;
return macro.VOID;
}
if (isPlaced()) {
model.previousPosition = null;
model._widgetManager.enablePicking();
model._apiSpecificRenderWindow.setCursor('pointer');
model._isDragging = false;
model.activeState = null;
model.widgetState.deactivate();
}
publicAPI.invokeEndInteractionEvent();
return macro.EVENT_ABORT;
};

publicAPI.handleMouseMove = (e) => {
if (!model._isDragging) {
model.activeState = null;
return macro.VOID;
}
if (!model.activeState) throw Error('no activestate');
const worldCoords = currentWorldCoords(e);
if (worldCoords) {
model.activeState.setOrigin(worldCoords);
model.previousPosition = worldCoords;
}
return macro.VOID;
};

publicAPI.grabFocus = () => {
moveHandle.setVisible(true);
model._isDragging = true;
model.activeState = moveHandle;
model._interactor.render();
};

publicAPI.loseFocus = () => {
model._isDragging = false;
model.activeState = null;
};
}
index.d.ts
import vtkAbstractWidget from '../../Core/AbstractWidget';
import { Vector3, Bounds } from '../../../types';

export interface ISeedWidgetHandleState {
getOrigin(): Vector3;
setOrigin(arg: Vector3): void;
getColor3(): string;
setColor3(arg: string):void;
getScale1(): number;
setScale1(arg: number): void;
getVisible(): boolean;
setVisible(arg: boolean):void
setShape(arg: string): void;
getShape(): string;
}

// The internal state of the widget.
export interface vtkSeedWidgetState {
// A handle that defines the location
getMoveHandle(): ISeedWidgetHandleState;
}

// The type of object returned by vtkWidgetManager.addWidget()
export interface vtkSeedWidgetHandle {
setCenter(center: Vector3): void;
}

export interface vtkSeedWidget {
// Abstract widget methods.
getWidgetState(): vtkSeedWidgetState;
onWidgetChange(fn: () => void): void;
placeWidget(bounds: Bounds): void;
setPlaceFactor(factor: number): void;
}

export interface ISeedWidgetInitialValues {}

export function newInstance(props?: ISeedWidgetInitialValues): vtkSeedWidget;

export const vtkSeedWidget: {
newInstance: typeof newInstance;
};

export default vtkSeedWidget;
index.js
import vtkAbstractWidgetFactory from 'vtk.js/Sources/Widgets/Core/AbstractWidgetFactory';
import vtkCubeHandleRepresentation from 'vtk.js/Sources/Widgets/Representations/CubeHandleRepresentation';
import macro from 'vtk.js/Sources/macros';

import widgetBehavior from './behavior';
import stateGenerator from './state';

function vtkSeedWidget(publicAPI, model) {
model.classHierarchy.push('vtkSeedWidget');

const superClass = { ...publicAPI };

model.methodsToLink = ['scaleInPixels'];

publicAPI.getRepresentationsForViewType = (viewType) => [
{
builder: vtkCubeHandleRepresentation,
labels: ['moveHandle'],
initialValues: {
useActiveColor: false,
},
},
];

publicAPI.setManipulator = (manipulator) => {
superClass.setManipulator(manipulator);
model.widgetState.getMoveHandle().setManipulator(manipulator);
};
}

const defaultValues = (initialValues) => ({
behavior: widgetBehavior,
widgetState: stateGenerator(),
...initialValues,
});

export function extend(publicAPI, model, initialValues = {}) {
Object.assign(model, defaultValues(initialValues));
vtkAbstractWidgetFactory.extend(publicAPI, model, initialValues);
macro.setGet(publicAPI, model, ['manipulator', 'widgetState']);
vtkSeedWidget(publicAPI, model);
}

export const newInstance = macro.newInstance(extend, 'vtkSeedWidget');

export default { newInstance, extend };
state.js
import vtkStateBuilder from 'vtk.js/Sources/Widgets/Core/StateBuilder';

// Defines the structure of the widget state.
// See https://kitware.github.io/vtk-js/docs/concepts_widgets.html.
export default function stateGenerator() {
return vtkStateBuilder
.createBuilder()
.addStateFromMixin({
labels: ['moveHandle'],
mixins: [
'origin',
'color3',
'scale1',
'direction',
'visible',
'manipulator',
],
name: 'moveHandle',
initialValues: {
scale1: 20,
visible: true,
direction: [0, 0, 1],
},
})
.build();
}