Added tooltips in top bar

main
Boris Sekachev 6 years ago
parent ff0a5659c7
commit 0fda72bb99

@ -3,12 +3,8 @@
// SPDX-License-Identifier: MIT
import React from 'react';
import {
Menu, Modal,
} from 'antd';
import { ClickParam } from 'antd/lib/menu/index';
import Menu, { ClickParam } from 'antd/lib/menu';
import Modal from 'antd/lib/modal';
import DumpSubmenu from 'components/actions-menu/dump-submenu';
import LoadSubmenu from 'components/actions-menu/load-submenu';

@ -3,30 +3,29 @@
// SPDX-License-Identifier: MIT
import React from 'react';
import {
Col,
Icon,
Modal,
Button,
Timeline,
Dropdown,
} from 'antd';
import { Col } from 'antd/lib/grid';
import Icon from 'antd/lib/icon';
import Modal from 'antd/lib/modal';
import Button from 'antd/lib/button';
import Timeline from 'antd/lib/timeline';
import Dropdown from 'antd/lib/dropdown';
import AnnotationMenuContainer from 'containers/annotation-page/top-bar/annotation-menu';
import {
MainMenuIcon,
SaveIcon,
UndoIcon,
RedoIcon,
} from '../../../icons';
} from 'icons';
interface Props {
saving: boolean;
savingStatuses: string[];
undoAction?: string;
redoAction?: string;
saveShortcut: string;
undoShortcut: string;
redoShortcut: string;
onSaveAnnotation(): void;
onUndoClick(): void;
onRedoClick(): void;
@ -38,6 +37,9 @@ function LeftGroup(props: Props): JSX.Element {
savingStatuses,
undoAction,
redoAction,
saveShortcut,
undoShortcut,
redoShortcut,
onSaveAnnotation,
onUndoClick,
onRedoClick,
@ -52,6 +54,7 @@ function LeftGroup(props: Props): JSX.Element {
</Button>
</Dropdown>
<Button
title={`Save current changes ${saveShortcut}`}
onClick={saving ? undefined : onSaveAnnotation}
type='link'
className={saving
@ -79,7 +82,7 @@ function LeftGroup(props: Props): JSX.Element {
</Modal>
</Button>
<Button
title={undoAction}
title={`Undo: ${undoAction} ${undoShortcut}`}
disabled={!undoAction}
style={{ pointerEvents: undoAction ? 'initial' : 'none', opacity: undoAction ? 1 : 0.5 }}
type='link'
@ -90,7 +93,7 @@ function LeftGroup(props: Props): JSX.Element {
<span>Undo</span>
</Button>
<Button
title={redoAction}
title={`Redo: ${redoAction} ${redoShortcut}`}
disabled={!redoAction}
style={{ pointerEvents: redoAction ? 'initial' : 'none', opacity: redoAction ? 1 : 0.5 }}
type='link'

@ -4,11 +4,9 @@
import React from 'react';
import {
Col,
Icon,
Tooltip,
} from 'antd';
import { Col } from 'antd/lib/grid';
import Icon from 'antd/lib/icon';
import Tooltip from 'antd/lib/tooltip';
import {
FirstIcon,
@ -19,10 +17,15 @@ import {
NextIcon,
ForwardJumpIcon,
LastIcon,
} from '../../../icons';
} from 'icons';
interface Props {
playing: boolean;
playPauseShortcut: string;
nextFrameShortcut: string;
previousFrameShortcut: string;
forwardShortcut: string;
backwardShortcut: string;
onSwitchPlay(): void;
onPrevFrame(): void;
onNextFrame(): void;
@ -35,6 +38,11 @@ interface Props {
function PlayerButtons(props: Props): JSX.Element {
const {
playing,
playPauseShortcut,
nextFrameShortcut,
previousFrameShortcut,
forwardShortcut,
backwardShortcut,
onSwitchPlay,
onPrevFrame,
onNextFrame,
@ -49,16 +57,16 @@ function PlayerButtons(props: Props): JSX.Element {
<Tooltip title='Go to the first frame'>
<Icon component={FirstIcon} onClick={onFirstFrame} />
</Tooltip>
<Tooltip title='Go back with a step'>
<Tooltip title={`Go back with a step ${backwardShortcut}`}>
<Icon component={BackJumpIcon} onClick={onBackward} />
</Tooltip>
<Tooltip title='Go back'>
<Tooltip title={`Go back ${previousFrameShortcut}`}>
<Icon component={PreviousIcon} onClick={onPrevFrame} />
</Tooltip>
{!playing
? (
<Tooltip title='Play'>
<Tooltip title={`Play ${playPauseShortcut}`}>
<Icon
component={PlayIcon}
onClick={onSwitchPlay}
@ -66,7 +74,7 @@ function PlayerButtons(props: Props): JSX.Element {
</Tooltip>
)
: (
<Tooltip title='Pause'>
<Tooltip title={`Pause ${playPauseShortcut}`}>
<Icon
component={PauseIcon}
onClick={onSwitchPlay}
@ -74,10 +82,10 @@ function PlayerButtons(props: Props): JSX.Element {
</Tooltip>
)}
<Tooltip title='Go next'>
<Tooltip title={`Go next ${nextFrameShortcut}`}>
<Icon component={NextIcon} onClick={onNextFrame} />
</Tooltip>
<Tooltip title='Go next with a step'>
<Tooltip title={`Go next with a step ${forwardShortcut}`}>
<Icon component={ForwardJumpIcon} onClick={onForward} />
</Tooltip>
<Tooltip title='Go to the last frame'>

@ -18,6 +18,7 @@ interface Props {
stopFrame: number;
frameNumber: number;
frameFilename: string;
focusFrameInputShortcut: string;
inputFrameRef: React.RefObject<InputNumber>;
onSliderChange(value: SliderValue): void;
onInputChange(value: number): void;
@ -30,6 +31,7 @@ function PlayerNavigation(props: Props): JSX.Element {
stopFrame,
frameNumber,
frameFilename,
focusFrameInputShortcut,
inputFrameRef,
onSliderChange,
onInputChange,
@ -72,26 +74,27 @@ function PlayerNavigation(props: Props): JSX.Element {
</Row>
</Col>
<Col>
<InputNumber
className='cvat-player-frame-selector'
type='number'
value={frameInputValue}
// https://stackoverflow.com/questions/38256332/in-react-whats-the-difference-between-onchange-and-oninput
onChange={(value: number | undefined) => {
if (typeof (value) === 'number') {
setFrameInputValue(Math.floor(
clamp(value, startFrame, stopFrame),
));
}
}}
onBlur={() => {
onInputChange(frameInputValue);
}}
onPressEnter={() => {
onInputChange(frameInputValue);
}}
ref={inputFrameRef}
/>
<Tooltip title={`Press ${focusFrameInputShortcut} to focus here`}>
<InputNumber
className='cvat-player-frame-selector'
type='number'
value={frameInputValue}
onChange={(value: number | undefined) => {
if (typeof (value) === 'number') {
setFrameInputValue(Math.floor(
clamp(value, startFrame, stopFrame),
));
}
}}
onBlur={() => {
onInputChange(frameInputValue);
}}
onPressEnter={() => {
onInputChange(frameInputValue);
}}
ref={inputFrameRef}
/>
</Tooltip>
</Col>
</>
);

@ -3,16 +3,13 @@
// SPDX-License-Identifier: MIT
import React from 'react';
import {
Col,
Icon,
Select,
Button,
} from 'antd';
import { Col } from 'antd/lib/grid';
import Icon from 'antd/lib/icon';
import Select from 'antd/lib/select';
import Button from 'antd/lib/button';
import { Workspace } from 'reducers/interfaces';
import { InfoIcon, FullscreenIcon } from '../../../icons';
import { InfoIcon, FullscreenIcon } from 'icons';
interface Props {
workspace: Workspace;

@ -3,18 +3,13 @@
// SPDX-License-Identifier: MIT
import React from 'react';
import {
Tooltip,
Select,
Table,
Modal,
Spin,
Icon,
Row,
Col,
} from 'antd';
import { Row, Col } from 'antd/lib/grid';
import Tooltip from 'antd/lib/tooltip';
import Select from 'antd/lib/select';
import Table from 'antd/lib/table';
import Modal from 'antd/lib/modal';
import Spin from 'antd/lib/spin';
import Icon from 'antd/lib/icon';
import Text from 'antd/lib/typography/Text';
interface Props {

@ -26,6 +26,15 @@ interface Props {
undoAction?: string;
redoAction?: string;
workspace: Workspace;
saveShortcut: string;
undoShortcut: string;
redoShortcut: string;
playPauseShortcut: string;
nextFrameShortcut: string;
previousFrameShortcut: string;
forwardShortcut: string;
backwardShortcut: string;
focusFrameInputShortcut: string;
changeWorkspace(workspace: Workspace): void;
showStatistics(): void;
onSwitchPlay(): void;
@ -56,6 +65,15 @@ export default function AnnotationTopBarComponent(props: Props): JSX.Element {
startFrame,
stopFrame,
workspace,
saveShortcut,
undoShortcut,
redoShortcut,
playPauseShortcut,
nextFrameShortcut,
previousFrameShortcut,
forwardShortcut,
backwardShortcut,
focusFrameInputShortcut,
showStatistics,
changeWorkspace,
onSwitchPlay,
@ -78,9 +96,12 @@ export default function AnnotationTopBarComponent(props: Props): JSX.Element {
<LeftGroup
saving={saving}
savingStatuses={savingStatuses}
onSaveAnnotation={onSaveAnnotation}
undoAction={undoAction}
redoAction={redoAction}
saveShortcut={saveShortcut}
undoShortcut={undoShortcut}
redoShortcut={redoShortcut}
onSaveAnnotation={onSaveAnnotation}
onUndoClick={onUndoClick}
onRedoClick={onRedoClick}
/>
@ -88,6 +109,11 @@ export default function AnnotationTopBarComponent(props: Props): JSX.Element {
<Row type='flex' align='middle'>
<PlayerButtons
playing={playing}
playPauseShortcut={playPauseShortcut}
nextFrameShortcut={nextFrameShortcut}
previousFrameShortcut={previousFrameShortcut}
forwardShortcut={forwardShortcut}
backwardShortcut={backwardShortcut}
onPrevFrame={onPrevFrame}
onNextFrame={onNextFrame}
onForward={onForward}
@ -101,6 +127,7 @@ export default function AnnotationTopBarComponent(props: Props): JSX.Element {
stopFrame={stopFrame}
frameNumber={frameNumber}
frameFilename={frameFilename}
focusFrameInputShortcut={focusFrameInputShortcut}
inputFrameRef={inputFrameRef}
onSliderChange={onSliderChange}
onInputChange={onInputChange}

@ -5,11 +5,9 @@
import React from 'react';
import copy from 'copy-to-clipboard';
import { connect } from 'react-redux';
import { withRouter } from 'react-router';
import { RouteComponentProps } from 'react-router-dom';
import { GlobalHotKeys, ExtendedKeyMapOptions } from 'react-hotkeys';
import InputNumber from 'antd/lib/input-number';
import { SliderValue } from 'antd/lib/slider';
@ -28,6 +26,7 @@ import {
import AnnotationTopBarComponent from 'components/annotation-page/top-bar/top-bar';
import { CombinedState, FrameSpeed, Workspace } from 'reducers/interfaces';
import { formatShortcuts } from 'utils/shortcuts';
interface StateToProps {
jobInstance: any;
@ -482,7 +481,7 @@ class AnnotationTopBarContainer extends React.PureComponent<Props> {
SAVE_JOB: keyMap.SAVE_JOB,
UNDO: keyMap.UNDO,
REDO: keyMap.REDO,
NEXT_FRAME: keyMap.SAVE_JOB,
NEXT_FRAME: keyMap.NEXT_FRAME,
PREV_FRAME: keyMap.PREV_FRAME,
FORWARD_FRAME: keyMap.FORWARD_FRAME,
BACKWARD_FRAME: keyMap.BACKWARD_FRAME,
@ -585,6 +584,15 @@ class AnnotationTopBarContainer extends React.PureComponent<Props> {
inputFrameRef={this.inputFrameRef}
undoAction={undoAction}
redoAction={redoAction}
saveShortcut={formatShortcuts(keyMap.SAVE_JOB)}
undoShortcut={formatShortcuts(keyMap.UNDO)}
redoShortcut={formatShortcuts(keyMap.REDO)}
playPauseShortcut={formatShortcuts(keyMap.PLAY_PAUSE)}
nextFrameShortcut={formatShortcuts(keyMap.NEXT_FRAME)}
previousFrameShortcut={formatShortcuts(keyMap.PREV_FRAME)}
forwardShortcut={formatShortcuts(keyMap.FORWARD_FRAME)}
backwardShortcut={formatShortcuts(keyMap.BACKWARD_FRAME)}
focusFrameInputShortcut={formatShortcuts(keyMap.FOCUS_INPUT_FRAME)}
onUndoClick={this.undo}
onRedoClick={this.redo}
/>

@ -0,0 +1,17 @@
// Copyright (C) 2020 Intel Corporation
//
// SPDX-License-Identifier: MIT
import { ExtendedKeyMapOptions } from 'react-hotkeys';
/* eslint-disable-next-line import/prefer-default-export */
export function formatShortcuts(shortcuts: ExtendedKeyMapOptions): string {
const list: string[] = shortcuts.sequences as string[];
return `[${list.map((shortcut: string): string => {
let keys = shortcut.split('+');
keys = keys.map((key: string): string => `${key ? key[0].toUpperCase() : key}${key.slice(1)}`);
keys = keys.join('+').split(/\s/g);
keys = keys.map((key: string): string => `${key ? key[0].toUpperCase() : key}${key.slice(1)}`);
return keys.join(' ');
}).join(', ')}]`;
}
Loading…
Cancel
Save