You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
374 lines
9.5 KiB
TypeScript
374 lines
9.5 KiB
TypeScript
import React from 'react';
|
|
import { connect } from 'react-redux';
|
|
|
|
import { SliderValue } from 'antd/lib/slider';
|
|
|
|
import {
|
|
changeFrameAsync,
|
|
switchPlay,
|
|
saveAnnotationsAsync,
|
|
collectStatisticsAsync,
|
|
showStatistics as showStatisticsAction,
|
|
undoActionAsync,
|
|
redoActionAsync,
|
|
} from 'actions/annotation-actions';
|
|
|
|
import AnnotationTopBarComponent from 'components/annotation-page/top-bar/top-bar';
|
|
import { CombinedState } from 'reducers/interfaces';
|
|
|
|
interface StateToProps {
|
|
jobInstance: any;
|
|
frameNumber: number;
|
|
frameStep: number;
|
|
playing: boolean;
|
|
saving: boolean;
|
|
canvasIsReady: boolean;
|
|
savingStatuses: string[];
|
|
undoAction?: string;
|
|
redoAction?: string;
|
|
}
|
|
|
|
interface DispatchToProps {
|
|
onChangeFrame(frame: number): void;
|
|
onSwitchPlay(playing: boolean): void;
|
|
onSaveAnnotation(sessionInstance: any): void;
|
|
showStatistics(sessionInstance: any): void;
|
|
undo(sessionInstance: any, frameNumber: any): void;
|
|
redo(sessionInstance: any, frameNumber: any): void;
|
|
}
|
|
|
|
function mapStateToProps(state: CombinedState): StateToProps {
|
|
const {
|
|
annotation: {
|
|
player: {
|
|
playing,
|
|
frame: {
|
|
number: frameNumber,
|
|
},
|
|
},
|
|
annotations: {
|
|
saving: {
|
|
uploading: saving,
|
|
statuses: savingStatuses,
|
|
},
|
|
history,
|
|
},
|
|
job: {
|
|
instance: jobInstance,
|
|
},
|
|
canvas: {
|
|
ready: canvasIsReady,
|
|
},
|
|
},
|
|
settings: {
|
|
player: {
|
|
frameStep,
|
|
},
|
|
},
|
|
} = state;
|
|
|
|
return {
|
|
frameStep,
|
|
playing,
|
|
canvasIsReady,
|
|
saving,
|
|
savingStatuses,
|
|
frameNumber,
|
|
jobInstance,
|
|
undoAction: history.undo[history.undo.length - 1],
|
|
redoAction: history.redo[history.redo.length - 1],
|
|
};
|
|
}
|
|
|
|
function mapDispatchToProps(dispatch: any): DispatchToProps {
|
|
return {
|
|
onChangeFrame(frame: number): void {
|
|
dispatch(changeFrameAsync(frame));
|
|
},
|
|
onSwitchPlay(playing: boolean): void {
|
|
dispatch(switchPlay(playing));
|
|
},
|
|
onSaveAnnotation(sessionInstance: any): void {
|
|
dispatch(saveAnnotationsAsync(sessionInstance));
|
|
},
|
|
showStatistics(sessionInstance: any): void {
|
|
dispatch(collectStatisticsAsync(sessionInstance));
|
|
dispatch(showStatisticsAction(true));
|
|
},
|
|
undo(sessionInstance: any, frameNumber: any): void {
|
|
dispatch(undoActionAsync(sessionInstance, frameNumber));
|
|
},
|
|
redo(sessionInstance: any, frameNumber: any): void {
|
|
dispatch(redoActionAsync(sessionInstance, frameNumber));
|
|
},
|
|
};
|
|
}
|
|
|
|
type Props = StateToProps & DispatchToProps;
|
|
class AnnotationTopBarContainer extends React.PureComponent<Props> {
|
|
public componentDidUpdate(): void {
|
|
const {
|
|
jobInstance,
|
|
frameNumber,
|
|
playing,
|
|
canvasIsReady,
|
|
onChangeFrame,
|
|
onSwitchPlay,
|
|
} = this.props;
|
|
|
|
if (playing && canvasIsReady) {
|
|
if (frameNumber < jobInstance.stopFrame) {
|
|
setTimeout(() => {
|
|
const { playing: stillPlaying } = this.props;
|
|
if (stillPlaying) {
|
|
onChangeFrame(frameNumber + 1);
|
|
}
|
|
});
|
|
} else {
|
|
onSwitchPlay(false);
|
|
}
|
|
}
|
|
}
|
|
|
|
private undo = (): void => {
|
|
const {
|
|
undo,
|
|
jobInstance,
|
|
frameNumber,
|
|
} = this.props;
|
|
|
|
undo(jobInstance, frameNumber);
|
|
};
|
|
|
|
private redo = (): void => {
|
|
const {
|
|
redo,
|
|
jobInstance,
|
|
frameNumber,
|
|
} = this.props;
|
|
|
|
redo(jobInstance, frameNumber);
|
|
};
|
|
|
|
private showStatistics = (): void => {
|
|
const {
|
|
jobInstance,
|
|
showStatistics,
|
|
} = this.props;
|
|
|
|
showStatistics(jobInstance);
|
|
};
|
|
|
|
private onSwitchPlay = (): void => {
|
|
const {
|
|
frameNumber,
|
|
jobInstance,
|
|
onSwitchPlay,
|
|
playing,
|
|
} = this.props;
|
|
|
|
if (playing) {
|
|
onSwitchPlay(false);
|
|
} else if (frameNumber < jobInstance.stopFrame) {
|
|
onSwitchPlay(true);
|
|
}
|
|
};
|
|
|
|
private onFirstFrame = (): void => {
|
|
const {
|
|
onChangeFrame,
|
|
frameNumber,
|
|
jobInstance,
|
|
playing,
|
|
onSwitchPlay,
|
|
} = this.props;
|
|
|
|
const newFrame = jobInstance.startFrame;
|
|
if (newFrame !== frameNumber) {
|
|
if (playing) {
|
|
onSwitchPlay(false);
|
|
}
|
|
onChangeFrame(newFrame);
|
|
}
|
|
};
|
|
|
|
private onBackward = (): void => {
|
|
const {
|
|
onChangeFrame,
|
|
frameNumber,
|
|
frameStep,
|
|
jobInstance,
|
|
playing,
|
|
onSwitchPlay,
|
|
} = this.props;
|
|
|
|
const newFrame = Math
|
|
.max(jobInstance.startFrame, frameNumber - frameStep);
|
|
if (newFrame !== frameNumber) {
|
|
if (playing) {
|
|
onSwitchPlay(false);
|
|
}
|
|
onChangeFrame(newFrame);
|
|
}
|
|
};
|
|
|
|
private onPrevFrame = (): void => {
|
|
const {
|
|
onChangeFrame,
|
|
frameNumber,
|
|
jobInstance,
|
|
playing,
|
|
onSwitchPlay,
|
|
} = this.props;
|
|
|
|
const newFrame = Math
|
|
.max(jobInstance.startFrame, frameNumber - 1);
|
|
if (newFrame !== frameNumber) {
|
|
if (playing) {
|
|
onSwitchPlay(false);
|
|
}
|
|
onChangeFrame(newFrame);
|
|
}
|
|
};
|
|
|
|
private onNextFrame = (): void => {
|
|
const {
|
|
onChangeFrame,
|
|
frameNumber,
|
|
jobInstance,
|
|
playing,
|
|
onSwitchPlay,
|
|
} = this.props;
|
|
|
|
const newFrame = Math
|
|
.min(jobInstance.stopFrame, frameNumber + 1);
|
|
if (newFrame !== frameNumber) {
|
|
if (playing) {
|
|
onSwitchPlay(false);
|
|
}
|
|
onChangeFrame(newFrame);
|
|
}
|
|
};
|
|
|
|
private onForward = (): void => {
|
|
const {
|
|
onChangeFrame,
|
|
frameNumber,
|
|
frameStep,
|
|
jobInstance,
|
|
playing,
|
|
onSwitchPlay,
|
|
} = this.props;
|
|
|
|
const newFrame = Math
|
|
.min(jobInstance.stopFrame, frameNumber + frameStep);
|
|
if (newFrame !== frameNumber) {
|
|
if (playing) {
|
|
onSwitchPlay(false);
|
|
}
|
|
onChangeFrame(newFrame);
|
|
}
|
|
};
|
|
|
|
private onLastFrame = (): void => {
|
|
const {
|
|
onChangeFrame,
|
|
frameNumber,
|
|
jobInstance,
|
|
playing,
|
|
onSwitchPlay,
|
|
} = this.props;
|
|
|
|
const newFrame = jobInstance.stopFrame;
|
|
if (newFrame !== frameNumber) {
|
|
if (playing) {
|
|
onSwitchPlay(false);
|
|
}
|
|
onChangeFrame(newFrame);
|
|
}
|
|
};
|
|
|
|
private onSaveAnnotation = (): void => {
|
|
const {
|
|
onSaveAnnotation,
|
|
jobInstance,
|
|
} = this.props;
|
|
|
|
onSaveAnnotation(jobInstance);
|
|
};
|
|
|
|
private onChangePlayerSliderValue = (value: SliderValue): void => {
|
|
const {
|
|
playing,
|
|
onSwitchPlay,
|
|
onChangeFrame,
|
|
} = this.props;
|
|
|
|
if (playing) {
|
|
onSwitchPlay(false);
|
|
}
|
|
onChangeFrame(value as number);
|
|
};
|
|
|
|
private onChangePlayerInputValue = (value: number | undefined): void => {
|
|
const {
|
|
onSwitchPlay,
|
|
playing,
|
|
onChangeFrame,
|
|
} = this.props;
|
|
|
|
if (typeof (value) !== 'undefined') {
|
|
if (playing) {
|
|
onSwitchPlay(false);
|
|
}
|
|
onChangeFrame(value);
|
|
}
|
|
};
|
|
|
|
public render(): JSX.Element {
|
|
const {
|
|
playing,
|
|
saving,
|
|
savingStatuses,
|
|
jobInstance: {
|
|
startFrame,
|
|
stopFrame,
|
|
},
|
|
frameNumber,
|
|
undoAction,
|
|
redoAction,
|
|
} = this.props;
|
|
|
|
return (
|
|
<AnnotationTopBarComponent
|
|
showStatistics={this.showStatistics}
|
|
onSwitchPlay={this.onSwitchPlay}
|
|
onSaveAnnotation={this.onSaveAnnotation}
|
|
onPrevFrame={this.onPrevFrame}
|
|
onNextFrame={this.onNextFrame}
|
|
onForward={this.onForward}
|
|
onBackward={this.onBackward}
|
|
onFirstFrame={this.onFirstFrame}
|
|
onLastFrame={this.onLastFrame}
|
|
onSliderChange={this.onChangePlayerSliderValue}
|
|
onInputChange={this.onChangePlayerInputValue}
|
|
playing={playing}
|
|
saving={saving}
|
|
savingStatuses={savingStatuses}
|
|
startFrame={startFrame}
|
|
stopFrame={stopFrame}
|
|
frameNumber={frameNumber}
|
|
undoAction={undoAction}
|
|
redoAction={redoAction}
|
|
onUndoClick={this.undo}
|
|
onRedoClick={this.redo}
|
|
/>
|
|
);
|
|
}
|
|
}
|
|
|
|
export default connect(
|
|
mapStateToProps,
|
|
mapDispatchToProps,
|
|
)(AnnotationTopBarContainer);
|