Skip to content

Commit f574c02

Browse files
committed
add keybinds (alt+up arrow, alt+down arrow) to iterate through the current active layer's annotation list
1 parent 2975b08 commit f574c02

File tree

3 files changed

+93
-12
lines changed

3 files changed

+93
-12
lines changed

src/ui/annotations.ts

Lines changed: 75 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,26 @@ interface AnnotationLayerViewAttachedState {
230230
listOffset: number;
231231
}
232232

233+
const moveToAnnotation = (
234+
layer: UserLayer,
235+
annotation: Annotation,
236+
state: AnnotationLayerState,
237+
) => {
238+
const chunkTransform = state.chunkTransform.value as ChunkTransformParameters;
239+
const { layerRank } = chunkTransform;
240+
const chunkPosition = new Float32Array(layerRank);
241+
const layerPosition = new Float32Array(layerRank);
242+
getCenterPosition(chunkPosition, annotation);
243+
matrix.transformPoint(
244+
layerPosition,
245+
chunkTransform.chunkToLayerTransform,
246+
layerRank + 1,
247+
chunkPosition,
248+
layerRank,
249+
);
250+
setLayerPosition(layer, chunkTransform, layerPosition);
251+
};
252+
233253
export class AnnotationLayerView extends Tab {
234254
private previousSelectedState:
235255
| {
@@ -940,18 +960,7 @@ export class AnnotationLayerView extends Tab {
940960
element.addEventListener("action:move-to-annotation", (event) => {
941961
event.stopPropagation();
942962
event.preventDefault();
943-
const { layerRank } = chunkTransform;
944-
const chunkPosition = new Float32Array(layerRank);
945-
const layerPosition = new Float32Array(layerRank);
946-
getCenterPosition(chunkPosition, annotation);
947-
matrix.transformPoint(
948-
layerPosition,
949-
chunkTransform.chunkToLayerTransform,
950-
layerRank + 1,
951-
chunkPosition,
952-
layerRank,
953-
);
954-
setLayerPosition(this.layer, chunkTransform, layerPosition);
963+
moveToAnnotation(this.layer, annotation, state);
955964
});
956965

957966
const selectionState = this.selectedAnnotationState.value;
@@ -1648,6 +1657,16 @@ export function UserLayerWithAnnotationsMixin<
16481657
this.annotationDisplayState.hoverState.value = undefined;
16491658
}),
16501659
);
1660+
this.registerDisposer(
1661+
this.registerLayerEvent("select-previous", () => {
1662+
this.changeSelectedIndex(-1);
1663+
}),
1664+
);
1665+
this.registerDisposer(
1666+
this.registerLayerEvent("select-next", () => {
1667+
this.changeSelectedIndex(1);
1668+
}),
1669+
);
16511670
}
16521671

16531672
initializeAnnotationLayerViewTab(tab: AnnotationLayerView) {
@@ -2141,6 +2160,50 @@ export function UserLayerWithAnnotationsMixin<
21412160
);
21422161
}
21432162

2163+
changeSelectedIndex = (offset: number) => {
2164+
const selectionState = this.manager.root.selectionState.value;
2165+
if (selectionState === undefined) return;
2166+
const layerSelectionState = selectionState.layers.find(
2167+
(s) => s.layer === this,
2168+
)?.state;
2169+
if (layerSelectionState === undefined) return;
2170+
const { annotationId } = layerSelectionState;
2171+
if (annotationId === undefined) return;
2172+
let annotationLayerState = this.annotationStates.states.find(
2173+
(x) =>
2174+
x.sourceIndex === layerSelectionState.annotationSourceIndex &&
2175+
(layerSelectionState.annotationSubsource === undefined ||
2176+
x.subsourceId === layerSelectionState.annotationSubsource),
2177+
);
2178+
if (annotationLayerState === undefined) return;
2179+
let annotationLayerStateIndex =
2180+
this.annotationStates.states.indexOf(annotationLayerState);
2181+
let { source } = annotationLayerState;
2182+
let annotations = Array.from(source);
2183+
let index = annotations.findIndex((x) => x.id === annotationId);
2184+
while (true) {
2185+
index = index + offset;
2186+
if (index === -1) {
2187+
// this only happens if offset is negative
2188+
annotationLayerStateIndex -= 1;
2189+
} else if (index === annotations.length) {
2190+
// this only happens if offset is positive
2191+
annotationLayerStateIndex += 1;
2192+
} else {
2193+
const annotation = annotations[index];
2194+
this.selectAnnotation(annotationLayerState, annotation.id, true);
2195+
moveToAnnotation(this, annotation, annotationLayerState);
2196+
return;
2197+
}
2198+
annotationLayerState =
2199+
this.annotationStates.states[annotationLayerStateIndex];
2200+
if (annotationLayerState === undefined) return;
2201+
source = annotationLayerState.source;
2202+
annotations = Array.from(source);
2203+
index = index === -1 ? annotations.length : 0;
2204+
}
2205+
};
2206+
21442207
toJSON() {
21452208
const x = super.toJSON();
21462209
x[ANNOTATION_COLOR_JSON_KEY] = this.annotationDisplayState.color.toJSON();

src/ui/default_input_event_bindings.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ export function getDefaultGlobalBindings() {
4848
map.set("space", "toggle-layout");
4949
map.set("shift+space", "toggle-layout-alternative");
5050
map.set("backslash", "toggle-show-statistics");
51+
52+
map.set("alt+arrowup", "select-previous");
53+
map.set("alt+arrowdown", "select-next");
5154
defaultGlobalBindings = map;
5255
}
5356
return defaultGlobalBindings;

src/viewer.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1027,6 +1027,21 @@ export class Viewer extends RefCounted implements ViewerState {
10271027
});
10281028
}
10291029

1030+
const sendEventToSelectedLayer = (type: string) => {
1031+
const selectedLayer = this.selectedLayer.layer?.layer;
1032+
if (selectedLayer) {
1033+
selectedLayer.dispatchLayerEvent(type);
1034+
}
1035+
};
1036+
1037+
this.bindAction("select-previous", () => {
1038+
sendEventToSelectedLayer("select-previous");
1039+
});
1040+
1041+
this.bindAction("select-next", () => {
1042+
sendEventToSelectedLayer("select-next");
1043+
});
1044+
10301045
for (const action of ["select", "star"]) {
10311046
this.bindAction(action, () => {
10321047
this.mouseState.updateUnconditionally();

0 commit comments

Comments
 (0)