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

Implement hot keys #134

Merged
merged 2 commits into from
Dec 15, 2020
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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ docker logs make_sense
| Zoom in | Editor | <kbd>⌥</kbd> + <kbd>+</kbd> | <kbd>Ctrl</kbd> + <kbd>+</kbd> |
| Zoom out | Editor | <kbd>⌥</kbd> + <kbd>-</kbd> | <kbd>Ctrl</kbd> + <kbd>-</kbd> |
| Move image | Editor | <kbd>Up</kbd> / <kbd>Down</kbd> / <kbd>Left</kbd> / <kbd>Right</kbd> | <kbd>Up</kbd> / <kbd>Down</kbd> / <kbd>Left</kbd> / <kbd>Right</kbd> |
| Select Label | Editor | <kbd>⌥</kbd> + <kbd>0-9</kbd> | <kbd>Ctrl</kbd> + <kbd>0-9</kbd> |
| Exit popup | Popup | <kbd>Escape</kbd> | <kbd>Escape</kbd> |

**Table 1.** Supported keyboard shortcuts
Expand Down
163 changes: 142 additions & 21 deletions src/logic/actions/ImageActions.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,152 @@
import {LabelsSelector} from "../../store/selectors/LabelsSelector";
import {store} from "../../index";
import {updateActiveImageIndex, updateActiveLabelId} from "../../store/labels/actionCreators";
import {ViewPortActions} from "./ViewPortActions";
import {EditorModel} from "../../staticModels/EditorModel";
import { LabelsSelector } from "../../store/selectors/LabelsSelector";
import { store } from "../../index";
import {
updateActiveImageIndex,
updateActiveLabelId,
updateActiveLabelNameId,
updateImageDataById,
} from "../../store/labels/actionCreators";
import { ViewPortActions } from "./ViewPortActions";
import { EditorModel } from "../../staticModels/EditorModel";
import { LabelType } from "../../data/enums/LabelType";
import {
ImageData,
LabelLine,
LabelPoint,
LabelPolygon,
LabelRect,
} from "../../store/labels/types";
import { LabelStatus } from "../../data/enums/LabelStatus";
import { remove } from "lodash";

export class ImageActions {
public static getPreviousImage(): void {
const currentImageIndex: number = LabelsSelector.getActiveImageIndex();
ImageActions.getImageByIndex(currentImageIndex - 1);
}
public static getPreviousImage(): void {
const currentImageIndex: number = LabelsSelector.getActiveImageIndex();
ImageActions.getImageByIndex(currentImageIndex - 1);
}

public static getNextImage(): void {
const currentImageIndex: number = LabelsSelector.getActiveImageIndex();
ImageActions.getImageByIndex(currentImageIndex + 1);
}

public static getImageByIndex(index: number): void {
if (EditorModel.viewPortActionsDisabled) return;

public static getNextImage(): void {
const currentImageIndex: number = LabelsSelector.getActiveImageIndex();
ImageActions.getImageByIndex(currentImageIndex + 1);
const imageCount: number = LabelsSelector.getImagesData().length;

if (index < 0 || index > imageCount - 1) {
return;
} else {
ViewPortActions.setZoom(1);
store.dispatch(updateActiveImageIndex(index));
store.dispatch(updateActiveLabelId(null));
}
}

public static getImageByIndex(index: number): void {
if (EditorModel.viewPortActionsDisabled) return;
public static setActiveLabelOnActiveImage(labelIndex: number): void {
const labelNames = LabelsSelector.getLabelNames();
if (labelNames.length < labelIndex + 1) {
return;
}

const imageCount: number = LabelsSelector.getImagesData().length;
const imageData: ImageData = LabelsSelector.getActiveImageData();
store.dispatch(
updateImageDataById(
imageData.id,
ImageActions.mapNewImageData(imageData, labelIndex)
)
);
store.dispatch(updateActiveLabelNameId(labelNames[1].id));
}

if (index < 0 || index > imageCount - 1) {
return;
private static mapNewImageData(
imageData: ImageData,
labelIndex: number
): ImageData {
const labelType: LabelType = LabelsSelector.getActiveLabelType();
const labelNames = LabelsSelector.getLabelNames();
let newImageData: ImageData = {
...imageData,
};
switch (labelType) {
case LabelType.POINT:
const point = LabelsSelector.getActivePointLabel();
newImageData.labelPoints = imageData.labelPoints.map(
(labelPoint: LabelPoint) => {
if (labelPoint.id === point.id) {
return {
...labelPoint,
labelId: labelNames[labelIndex].id,
status: LabelStatus.ACCEPTED,
};
}
return labelPoint;
}
);
store.dispatch(updateActiveLabelId(point.id));
break;
case LabelType.LINE:
const line = LabelsSelector.getActiveLineLabel();
newImageData.labelLines = imageData.labelLines.map(
(labelLine: LabelLine) => {
if (labelLine.id === line.id) {
return {
...labelLine,
labelId: labelNames[labelIndex].id,
status: LabelStatus.ACCEPTED,
};
}
return labelLine;
}
);
store.dispatch(updateActiveLabelId(line.id));
break;
case LabelType.RECT:
const rect = LabelsSelector.getActiveRectLabel();
newImageData.labelRects = imageData.labelRects.map(
(labelRectangle: LabelRect) => {
if (labelRectangle.id === rect.id) {
return {
...labelRectangle,
labelId: labelNames[labelIndex].id,
status: LabelStatus.ACCEPTED,
};
}
return labelRectangle;
}
);
store.dispatch(updateActiveLabelId(rect.id));
break;
case LabelType.POLYGON:
const polygon = LabelsSelector.getActivePolygonLabel();
newImageData.labelPolygons = imageData.labelPolygons.map(
(labelPolygon: LabelPolygon) => {
if (labelPolygon.id === polygon.id) {
return {
...labelPolygon,
labelId: labelNames[labelIndex].id,
status: LabelStatus.ACCEPTED,
};
}
return labelPolygon;
}
);
store.dispatch(updateActiveLabelId(polygon.id));
break;
case LabelType.IMAGE_RECOGNITION:
const labelId: string = labelNames[labelIndex].id;
if (imageData.labelNameIds.includes(labelId)) {
newImageData.labelNameIds = remove(
imageData.labelNameIds,
(element: string) => element !== labelId
);
} else {
ViewPortActions.setZoom(1);
store.dispatch(updateActiveImageIndex(index));
store.dispatch(updateActiveLabelId(null));
newImageData.labelNameIds = imageData.labelNameIds.concat(labelId);
}
break;
}
}

return newImageData;
}
}
70 changes: 70 additions & 0 deletions src/logic/context/EditorContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,76 @@ export class EditorContext extends BaseContext {
action: (event: KeyboardEvent) => {
LabelActions.deleteActiveLabel();
}
},
{
keyCombo: PlatformUtil.isMac(window.navigator.userAgent) ? ["Alt", "0"] : ["Control", "0"],
action: (event: KeyboardEvent) => {
ImageActions.setActiveLabelOnActiveImage(0);
EditorActions.fullRender();
}
},
{
keyCombo: PlatformUtil.isMac(window.navigator.userAgent) ? ["Alt", "1"] : ["Control", "1"],
action: (event: KeyboardEvent) => {
ImageActions.setActiveLabelOnActiveImage(1);
EditorActions.fullRender();
}
},
{
keyCombo: PlatformUtil.isMac(window.navigator.userAgent) ? ["Alt", "2"] : ["Control", "2"],
action: (event: KeyboardEvent) => {
ImageActions.setActiveLabelOnActiveImage(2);
EditorActions.fullRender();
}
},
{
keyCombo: PlatformUtil.isMac(window.navigator.userAgent) ? ["Alt", "3"] : ["Control", "3"],
action: (event: KeyboardEvent) => {
ImageActions.setActiveLabelOnActiveImage(3);
EditorActions.fullRender();
}
},
{
keyCombo: PlatformUtil.isMac(window.navigator.userAgent) ? ["Alt", "4"] : ["Control", "4"],
action: (event: KeyboardEvent) => {
ImageActions.setActiveLabelOnActiveImage(4);
EditorActions.fullRender();
}
},
{
keyCombo: PlatformUtil.isMac(window.navigator.userAgent) ? ["Alt", "5"] : ["Control", "5"],
action: (event: KeyboardEvent) => {
ImageActions.setActiveLabelOnActiveImage(5);
EditorActions.fullRender();
}
},
{
keyCombo: PlatformUtil.isMac(window.navigator.userAgent) ? ["Alt", "6"] : ["Control", "6"],
action: (event: KeyboardEvent) => {
ImageActions.setActiveLabelOnActiveImage(6);
EditorActions.fullRender();
}
},
{
keyCombo: PlatformUtil.isMac(window.navigator.userAgent) ? ["Alt", "7"] : ["Control", "7"],
action: (event: KeyboardEvent) => {
ImageActions.setActiveLabelOnActiveImage(7);
EditorActions.fullRender();
}
},
{
keyCombo: PlatformUtil.isMac(window.navigator.userAgent) ? ["Alt", "8"] : ["Control", "8"],
action: (event: KeyboardEvent) => {
ImageActions.setActiveLabelOnActiveImage(8);
EditorActions.fullRender();
}
},
{
keyCombo: PlatformUtil.isMac(window.navigator.userAgent) ? ["Alt", "9"] : ["Control", "9"],
action: (event: KeyboardEvent) => {
ImageActions.setActiveLabelOnActiveImage(9);
EditorActions.fullRender();
}
}
];
}