Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(scrollEvent): added out of bounds scroll #476

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions common/reviews/api/core.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,8 @@ export enum EVENTS {
// (undocumented)
VOLUME_NEW_IMAGE = "CORNERSTONE_VOLUME_NEW_IMAGE",
// (undocumented)
VOLUME_SCROLL_OUT_OF_BOUNDS = "CORNERSTONE_VOLUME_SCROLL_OUT_OF_BOUNDS",
// (undocumented)
VOLUME_VIEWPORT_NEW_VOLUME = "CORNERSTONE_VOLUME_VIEWPORT_NEW_VOLUME"
}

Expand Down Expand Up @@ -791,6 +793,11 @@ function getVolumeViewportsContainingSameVolumes(targetViewport: IVolumeViewport
function getVolumeViewportScrollInfo(viewport: IVolumeViewport, volumeId: string): {
numScrollSteps: number;
currentStepIndex: number;
sliceRangeInfo: {
sliceRange: ActorSliceRange;
spacingInNormalDirection: number;
camera: ICamera;
};
};

// @public (undocumented)
Expand Down
3 changes: 2 additions & 1 deletion common/reviews/api/streaming-image-volume-loader.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -463,8 +463,9 @@ enum Events {

VOLUME_NEW_IMAGE = 'CORNERSTONE_VOLUME_NEW_IMAGE',

VOLUME_VIEWPORT_NEW_VOLUME = 'CORNERSTONE_VOLUME_VIEWPORT_NEW_VOLUME',
VOLUME_SCROLL_OUT_OF_BOUNDS = 'CORNERSTONE_VOLUME_SCROLL_OUT_OF_BOUNDS',

VOLUME_VIEWPORT_NEW_VOLUME = 'CORNERSTONE_VOLUME_VIEWPORT_NEW_VOLUME',
// IMAGE_CACHE_FULL = 'CORNERSTONE_IMAGE_CACHE_FULL',
// PRE_RENDER = 'CORNERSTONE_PRE_RENDER',
// ELEMENT_RESIZED = 'CORNERSTONE_ELEMENT_RESIZED',
Expand Down
18 changes: 17 additions & 1 deletion common/reviews/api/tools.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -1897,7 +1897,9 @@ declare namespace EventTypes_2 {
MouseDoubleClickEventDetail,
MouseDoubleClickEventType,
MouseWheelEventDetail,
MouseWheelEventType
MouseWheelEventType,
VolumeScrollOutOfBoundsEventDetail,
VolumeScrollOutOfBoundsEventType
}
}

Expand Down Expand Up @@ -5438,6 +5440,20 @@ export class VolumeRotateMouseWheelTool extends BaseTool {
// @public (undocumented)
type VolumeScalarData = Float32Array | Uint8Array | Uint16Array | Int16Array;

// @public (undocumented)
type VolumeScrollOutOfBoundsEventDetail = {
volumeId: string;
viewport: Types_2.IVolumeViewport;
desiredStepIndex: number;
currentStepIndex: number;
delta: number;
numScrollSteps: number;
currentImageId: string;
};

// @public (undocumented)
type VolumeScrollOutOfBoundsEventType = Types_2.CustomEventType<VolumeScrollOutOfBoundsEventDetail>;

// @public
type VolumeViewportProperties = {
voiRange?: VOIRange;
Expand Down
5 changes: 5 additions & 0 deletions packages/core/src/enums/Events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,11 @@ enum Events {
*/
GEOMETRY_CACHE_GEOMETRY_ADDED = 'CORNERSTONE_GEOMETRY_CACHE_GEOMETRY_ADDED',

/**
* Triggers when the scroll function is called with a delta that is out of bounds.
* This is usually for signaling that the user may want a different volume for partially loaded volumes which is meant to optimize memory.
*/
VOLUME_SCROLL_OUT_OF_BOUNDS = 'CORNERSTONE_VOLUME_SCROLL_OUT_OF_BOUNDS',
// IMAGE_CACHE_FULL = 'CORNERSTONE_IMAGE_CACHE_FULL',
// PRE_RENDER = 'CORNERSTONE_PRE_RENDER',
// ELEMENT_RESIZED = 'CORNERSTONE_ELEMENT_RESIZED',
Expand Down
16 changes: 11 additions & 5 deletions packages/core/src/utilities/getVolumeViewportScrollInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,8 @@ function getVolumeViewportScrollInfo(
viewport: IVolumeViewport,
volumeId: string
) {
const { sliceRange, spacingInNormalDirection } = getVolumeSliceRangeInfo(
viewport,
volumeId
);
const { sliceRange, spacingInNormalDirection, camera } =
getVolumeSliceRangeInfo(viewport, volumeId);

const { min, max, current } = sliceRange;

Expand All @@ -26,7 +24,15 @@ function getVolumeViewportScrollInfo(
const floatingStepNumber = fraction * numScrollSteps;
const currentStepIndex = Math.round(floatingStepNumber);

return { numScrollSteps, currentStepIndex };
return {
numScrollSteps,
currentStepIndex,
sliceRangeInfo: {
sliceRange,
spacingInNormalDirection,
camera,
},
};
}

export default getVolumeViewportScrollInfo;
21 changes: 21 additions & 0 deletions packages/tools/src/types/EventTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,19 @@ type MouseWheelEventDetail = NormalizedInteractionEventDetail &
points: IPoints;
};

/**
* Volume Scroll Out of Bounds event detail
*/
type VolumeScrollOutOfBoundsEventDetail = {
volumeId: string;
viewport: Types.IVolumeViewport;
desiredStepIndex: number;
currentStepIndex: number;
delta: number; // difference between the desired and current frame
numScrollSteps: number; // total scroll steps in the volume
currentImageId: string; // get ImageId (ImageIndex for in-plane acquisition)
};

/////////////////////////////
//
//
Expand Down Expand Up @@ -585,6 +598,12 @@ type MouseDoubleClickEventType =
*/
type MouseWheelEventType = Types.CustomEventType<MouseWheelEventDetail>;

/**
* Event for volume scroll out of bounds
*/
type VolumeScrollOutOfBoundsEventType =
Types.CustomEventType<VolumeScrollOutOfBoundsEventDetail>;

export {
InteractionStartType,
InteractionEndType,
Expand Down Expand Up @@ -654,4 +673,6 @@ export {
MouseDoubleClickEventType,
MouseWheelEventDetail,
MouseWheelEventType,
VolumeScrollOutOfBoundsEventDetail,
VolumeScrollOutOfBoundsEventType,
};
33 changes: 31 additions & 2 deletions packages/tools/src/utilities/scroll.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ import {
StackViewport,
Types,
VolumeViewport,
eventTarget,
EVENTS,
utilities as csUtils,
} from '@cornerstonejs/core';
import { ScrollOptions } from '../types';
import { ScrollOptions, EventTypes } from '../types';

/**
* It scrolls one slice in the Stack or Volume Viewport, it uses the options provided
Expand Down Expand Up @@ -36,7 +38,8 @@ export function scrollVolume(
volumeId: string,
delta: number
) {
const sliceRangeInfo = csUtils.getVolumeSliceRangeInfo(viewport, volumeId);
const { numScrollSteps, currentStepIndex, sliceRangeInfo } =
csUtils.getVolumeViewportScrollInfo(viewport, volumeId);

if (!sliceRangeInfo) {
return;
Expand All @@ -59,4 +62,30 @@ export function scrollVolume(
position: newPosition,
});
viewport.render();

const desiredStepIndex = currentStepIndex + delta;

if (
(desiredStepIndex > numScrollSteps || desiredStepIndex < 0) &&
viewport.getCurrentImageId() // Check that we are in the plane of acquistion
) {
// One common use case of this trigger might be to load the next
// volume in a time series or the next segment of a partially loaded volume.

const VolumeScrollEventDetail = {
volumeId,
viewport,
delta,
desiredStepIndex,
currentStepIndex,
numScrollSteps,
currentImageId: viewport.getCurrentImageId(),
};

csUtils.triggerEvent(
eventTarget,
EVENTS.VOLUME_SCROLL_OUT_OF_BOUNDS,
VolumeScrollEventDetail as EventTypes.VolumeScrollOutOfBoundsEventDetail
);
}
}