Skip to content

Commit

Permalink
add keybinds (alt+up arrow, alt+down arrow) to iterate through the cu…
Browse files Browse the repository at this point in the history
…rrent active layer's annotation list
  • Loading branch information
chrisj committed Oct 1, 2024
1 parent 2975b08 commit f574c02
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 12 deletions.
87 changes: 75 additions & 12 deletions src/ui/annotations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,26 @@ interface AnnotationLayerViewAttachedState {
listOffset: number;
}

const moveToAnnotation = (
layer: UserLayer,
annotation: Annotation,
state: AnnotationLayerState,
) => {
const chunkTransform = state.chunkTransform.value as ChunkTransformParameters;
const { layerRank } = chunkTransform;
const chunkPosition = new Float32Array(layerRank);
const layerPosition = new Float32Array(layerRank);
getCenterPosition(chunkPosition, annotation);
matrix.transformPoint(
layerPosition,
chunkTransform.chunkToLayerTransform,
layerRank + 1,
chunkPosition,
layerRank,
);
setLayerPosition(layer, chunkTransform, layerPosition);
};

export class AnnotationLayerView extends Tab {
private previousSelectedState:
| {
Expand Down Expand Up @@ -940,18 +960,7 @@ export class AnnotationLayerView extends Tab {
element.addEventListener("action:move-to-annotation", (event) => {
event.stopPropagation();
event.preventDefault();
const { layerRank } = chunkTransform;
const chunkPosition = new Float32Array(layerRank);
const layerPosition = new Float32Array(layerRank);
getCenterPosition(chunkPosition, annotation);
matrix.transformPoint(
layerPosition,
chunkTransform.chunkToLayerTransform,
layerRank + 1,
chunkPosition,
layerRank,
);
setLayerPosition(this.layer, chunkTransform, layerPosition);
moveToAnnotation(this.layer, annotation, state);
});

const selectionState = this.selectedAnnotationState.value;
Expand Down Expand Up @@ -1648,6 +1657,16 @@ export function UserLayerWithAnnotationsMixin<
this.annotationDisplayState.hoverState.value = undefined;
}),
);
this.registerDisposer(
this.registerLayerEvent("select-previous", () => {
this.changeSelectedIndex(-1);
}),
);
this.registerDisposer(
this.registerLayerEvent("select-next", () => {
this.changeSelectedIndex(1);
}),
);
}

initializeAnnotationLayerViewTab(tab: AnnotationLayerView) {
Expand Down Expand Up @@ -2141,6 +2160,50 @@ export function UserLayerWithAnnotationsMixin<
);
}

changeSelectedIndex = (offset: number) => {
const selectionState = this.manager.root.selectionState.value;
if (selectionState === undefined) return;
const layerSelectionState = selectionState.layers.find(
(s) => s.layer === this,
)?.state;
if (layerSelectionState === undefined) return;
const { annotationId } = layerSelectionState;
if (annotationId === undefined) return;
let annotationLayerState = this.annotationStates.states.find(
(x) =>
x.sourceIndex === layerSelectionState.annotationSourceIndex &&
(layerSelectionState.annotationSubsource === undefined ||
x.subsourceId === layerSelectionState.annotationSubsource),
);
if (annotationLayerState === undefined) return;
let annotationLayerStateIndex =
this.annotationStates.states.indexOf(annotationLayerState);
let { source } = annotationLayerState;
let annotations = Array.from(source);
let index = annotations.findIndex((x) => x.id === annotationId);
while (true) {
index = index + offset;
if (index === -1) {
// this only happens if offset is negative
annotationLayerStateIndex -= 1;
} else if (index === annotations.length) {
// this only happens if offset is positive
annotationLayerStateIndex += 1;
} else {
const annotation = annotations[index];
this.selectAnnotation(annotationLayerState, annotation.id, true);
moveToAnnotation(this, annotation, annotationLayerState);
return;
}
annotationLayerState =
this.annotationStates.states[annotationLayerStateIndex];
if (annotationLayerState === undefined) return;
source = annotationLayerState.source;
annotations = Array.from(source);
index = index === -1 ? annotations.length : 0;
}
};

toJSON() {
const x = super.toJSON();
x[ANNOTATION_COLOR_JSON_KEY] = this.annotationDisplayState.color.toJSON();
Expand Down
3 changes: 3 additions & 0 deletions src/ui/default_input_event_bindings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ export function getDefaultGlobalBindings() {
map.set("space", "toggle-layout");
map.set("shift+space", "toggle-layout-alternative");
map.set("backslash", "toggle-show-statistics");

map.set("alt+arrowup", "select-previous");
map.set("alt+arrowdown", "select-next");
defaultGlobalBindings = map;
}
return defaultGlobalBindings;
Expand Down
15 changes: 15 additions & 0 deletions src/viewer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1027,6 +1027,21 @@ export class Viewer extends RefCounted implements ViewerState {
});
}

const sendEventToSelectedLayer = (type: string) => {
const selectedLayer = this.selectedLayer.layer?.layer;
if (selectedLayer) {
selectedLayer.dispatchLayerEvent(type);
}
};

this.bindAction("select-previous", () => {
sendEventToSelectedLayer("select-previous");
});

this.bindAction("select-next", () => {
sendEventToSelectedLayer("select-next");
});

for (const action of ["select", "star"]) {
this.bindAction(action, () => {
this.mouseState.updateUnconditionally();
Expand Down

0 comments on commit f574c02

Please sign in to comment.