feat(DoubleClick): double click a viewport to one up and back (#3285)

* feat(DoubleClick): double click a viewport to one up and back

Added a toggleOneUp command that puts the active viewport into a 1x1 grid layout
and it toggles out of 'one-up' by restoring its saved 'toggleOneUpViewportGridStore'
from the StateSyncService.
Added double click customization for the Cornerstone extension with the
default double click handling being the toggleOneUp command.
Added a cypress test for the double click functionality.

* PR feedback:
- tracked viewport measurements no longer show as dashed when toggling one up
- disallowed double clicking near a measurement
- updated cornerstone3D dependencies to fix double click of TMTV and volume viewport 3D
- created ViewportGridService.getLayoutOptionsFromState

* Updated the ViewportGridService docs.

* Switched to using 'cornerstoneViewportClickCommands' and consistency with the context menu clicks.
This commit is contained in:
Joe Boccanfuso authored and GitHub committed 2023-03-29 15:39:51 -04:00
1 parent 4734b3bac6
commit d5ff590dfc
14 files changed
+402 -40

No files matched your search

@@ -2,6 +2,8 @@ import { PubSubService } from '../_shared/pubSubServiceInterface';
const EVENTS = {
ACTIVE_VIEWPORT_INDEX_CHANGED: 'event::activeviewportindexchanged',
LAYOUT_CHANGED: 'event::layoutChanged',
GRID_STATE_CHANGED: 'event::gridStateChanged',
};
class ViewportGridService extends PubSubService {
@@ -101,12 +103,26 @@ class ViewportGridService extends PubSubService {
* options that is initially provided as {} (eg to store intermediate state)
* The function returns a viewport object to use at the given position.
*/
public setLayout({ numCols, numRows, findOrCreateViewport = undefined }) {
public setLayout({
numCols,
numRows,
layoutOptions,
layoutType = 'grid',
activeViewportIndex = undefined,
findOrCreateViewport = undefined,
}) {
this.serviceImplementation._setLayout({
numCols,
numRows,
layoutOptions,
layoutType,
activeViewportIndex,
findOrCreateViewport,
});
this._broadcastEvent(this.EVENTS.LAYOUT_CHANGED, {
numCols,
numRows,
});
}
public reset() {
@@ -125,11 +141,25 @@ class ViewportGridService extends PubSubService {
public set(state) {
this.serviceImplementation._set(state);
this._broadcastEvent(this.EVENTS.GRID_STATE_CHANGED, {
state,
});
}
public getNumViewportPanes() {
return this.serviceImplementation._getNumViewportPanes();
}
public getLayoutOptionsFromState(state) {
return state.viewports.map(viewport => {
return {
x: viewport.x,
y: viewport.y,
width: viewport.width,
height: viewport.height,
};
});
}
}
export default ViewportGridService;
+1 -1
View File
@@ -6,5 +6,5 @@ export interface Command {
/** A set of commands, typically contained in a tool item or other configuration */
export interface Commands {
commands: Commands[];
commands: Command[];
}
+2
View File
@@ -32,6 +32,7 @@ import {
sortingCriteria,
seriesSortCriteria,
} from './sortStudy';
import { subscribeToNextViewportGridChange } from './subscribeToNextViewportGridChange';
// Commented out unused functionality.
// Need to implement new mechanism for derived displaySets using the displaySetManager.
@@ -69,6 +70,7 @@ const utils = {
debounce,
roundNumber,
downloadCSVReport,
subscribeToNextViewportGridChange,
};
export {
+1
View File
@@ -35,6 +35,7 @@ describe('Top level exports', () => {
'resolveObjectPath',
'hierarchicalListUtils',
'progressTrackingUtils',
'subscribeToNextViewportGridChange',
].sort();
const exports = Object.keys(utils.default).sort();
@@ -0,0 +1,37 @@
import { ViewportGridService } from '../services';
/**
* Subscribes to the very next LAYOUT_CHANGED or GRID_STATE_CHANGED event that
* is not currently on the event queue. The subscriptions are made on a 'zero'
* timeout so as to avoid responding to any of those events currently on the event queue.
* The subscription persists only for a single invocation of either event.
* Once either event is fired, the subscriptions are unsubscribed.
* @param viewportGridService the viewport grid service to subscribe to
* @param gridChangeCallback the callback
*/
function subscribeToNextViewportGridChange(
viewportGridService: ViewportGridService,
gridChangeCallback: (arg: unknown) => void
): void {
const subscriber = () => {
const callback = (callbackProps: unknown) => {
subscriptions.forEach(subscription => subscription.unsubscribe());
gridChangeCallback(callbackProps);
};
const subscriptions = [
viewportGridService.subscribe(
viewportGridService.EVENTS.LAYOUT_CHANGED,
callback
),
viewportGridService.subscribe(
viewportGridService.EVENTS.GRID_STATE_CHANGED,
callback
),
];
};
window.setTimeout(subscriber, 0);
}
export { subscribeToNextViewportGridChange };