CVAT UI: batch of fixes (#2084)

* fixed object item border color

* Fixed default collapsed prop in object item

* Added color picker for shape outline

* Added CHANGELOG, increased npm version

* Fixed object details collapsing

* Fixed default collapsed
main
Dmitry Kalinin 6 years ago committed by GitHub
parent 510191f64b
commit 0e37d70b1a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -33,6 +33,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Ability to configure email verification for new users (<https://github.com/opencv/cvat/pull/1929>)
- Link to django admin page from UI (<https://github.com/opencv/cvat/pull/2068>)
- Notification message when users use wrong browser (<https://github.com/opencv/cvat/pull/2070>)
- Annotation in process outline color wheel (<https://github.com/opencv/cvat/pull/2084>)
### Changed
- Shape coordinates are rounded to 2 digits in dumped annotations (<https://github.com/opencv/cvat/pull/1970>)
@ -44,6 +45,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Fixed a case in which exported masks could have wrong color order (<https://github.com/opencv/cvat/issues/2032>)
- Fixed error with creating task with labels with the same name (<https://github.com/opencv/cvat/pull/2031>)
- Django RQ dashboard view (<https://github.com/opencv/cvat/pull/2069>)
- Object's details menu settings (<https://github.com/opencv/cvat/pull/2084>)
-
## [1.1.0-beta] - 2020-08-03
### Added

@ -1,6 +1,6 @@
{
"name": "cvat-ui",
"version": "1.9.0",
"version": "1.9.1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

@ -1,6 +1,6 @@
{
"name": "cvat-ui",
"version": "1.9.0",
"version": "1.9.1",
"description": "CVAT single-page application",
"main": "src/index.tsx",
"scripts": {

@ -94,8 +94,8 @@ export const registerAsync = (
dispatch(authActions.register());
try {
const user = await cvat.server.register(username, firstName, lastName, email, password1, password2,
confirmations);
const user = await cvat.server.register(username, firstName, lastName, email, password1,
password2, confirmations);
dispatch(authActions.registerSuccess(user));
} catch (error) {

@ -17,7 +17,7 @@ export enum SettingsActionTypes {
CHANGE_SHAPES_OPACITY = 'CHANGE_SHAPES_OPACITY',
CHANGE_SELECTED_SHAPES_OPACITY = 'CHANGE_SELECTED_SHAPES_OPACITY',
CHANGE_SHAPES_COLOR_BY = 'CHANGE_SHAPES_COLOR_BY',
CHANGE_SHAPES_BLACK_BORDERS = 'CHANGE_SHAPES_BLACK_BORDERS',
CHANGE_SHAPES_OUTLINED_BORDERS = 'CHANGE_SHAPES_OUTLINED_BORDERS',
CHANGE_SHAPES_SHOW_PROJECTIONS = 'CHANGE_SHAPES_SHOW_PROJECTIONS',
CHANGE_SHOW_UNLABELED_REGIONS = 'CHANGE_SHOW_UNLABELED_REGIONS',
CHANGE_FRAME_STEP = 'CHANGE_FRAME_STEP',
@ -63,11 +63,12 @@ export function changeShapesColorBy(colorBy: ColorBy): AnyAction {
};
}
export function changeShapesBlackBorders(blackBorders: boolean): AnyAction {
export function changeShapesOutlinedBorders(outlined: boolean, color: string): AnyAction {
return {
type: SettingsActionTypes.CHANGE_SHAPES_BLACK_BORDERS,
type: SettingsActionTypes.CHANGE_SHAPES_OUTLINED_BORDERS,
payload: {
blackBorders,
outlined,
color,
},
};
}

@ -22,7 +22,7 @@ $info-icon-color: #0074d9;
$objects-bar-tabs-color: #bebebe;
$objects-bar-icons-color: #242424; // #6e6e6e
$active-label-background-color: #d8ecff;
$object-item-border-color: #000;
$object-item-border-color: rgba(0, 0, 0, 0.7);
$slider-color: #1890ff;
$monospaced-fonts-stack: Consolas, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace;

@ -11,6 +11,8 @@ import Slider, { SliderValue } from 'antd/lib/slider';
import Checkbox, { CheckboxChangeEvent } from 'antd/lib/checkbox';
import Collapse from 'antd/lib/collapse';
import ColorPicker from 'components/annotation-page/standard-workspace/objects-side-bar/color-picker';
import { ColorizeIcon } from 'icons';
import { ColorBy, CombinedState } from 'reducers/interfaces';
import {
collapseAppearance as collapseAppearanceAction,
@ -20,17 +22,19 @@ import {
changeShapesColorBy as changeShapesColorByAction,
changeShapesOpacity as changeShapesOpacityAction,
changeSelectedShapesOpacity as changeSelectedShapesOpacityAction,
changeShapesBlackBorders as changeShapesBlackBordersAction,
changeShapesOutlinedBorders as changeShapesOutlinedBordersAction,
changeShowBitmap as changeShowBitmapAction,
changeShowProjections as changeShowProjectionsAction,
} from 'actions/settings-actions';
import Button from 'antd/lib/button';
interface StateToProps {
appearanceCollapsed: boolean;
colorBy: ColorBy;
opacity: number;
selectedOpacity: number;
blackBorders: boolean;
outlined: boolean;
outlineColor: string;
showBitmap: boolean;
showProjections: boolean;
}
@ -40,7 +44,7 @@ interface DispatchToProps {
changeShapesColorBy(event: RadioChangeEvent): void;
changeShapesOpacity(event: SliderValue): void;
changeSelectedShapesOpacity(event: SliderValue): void;
changeShapesBlackBorders(event: CheckboxChangeEvent): void;
changeShapesOutlinedBorders(outlined: boolean, color: string): void;
changeShowBitmap(event: CheckboxChangeEvent): void;
changeShowProjections(event: CheckboxChangeEvent): void;
}
@ -72,7 +76,8 @@ function mapStateToProps(state: CombinedState): StateToProps {
colorBy,
opacity,
selectedOpacity,
blackBorders,
outlined,
outlineColor,
showBitmap,
showProjections,
},
@ -84,7 +89,8 @@ function mapStateToProps(state: CombinedState): StateToProps {
colorBy,
opacity,
selectedOpacity,
blackBorders,
outlined,
outlineColor,
showBitmap,
showProjections,
};
@ -119,8 +125,8 @@ function mapDispatchToProps(dispatch: Dispatch<AnyAction>): DispatchToProps {
changeSelectedShapesOpacity(value: SliderValue): void {
dispatch(changeSelectedShapesOpacityAction(value as number));
},
changeShapesBlackBorders(event: CheckboxChangeEvent): void {
dispatch(changeShapesBlackBordersAction(event.target.checked));
changeShapesOutlinedBorders(outlined: boolean, color: string): void {
dispatch(changeShapesOutlinedBordersAction(outlined, color));
},
changeShowBitmap(event: CheckboxChangeEvent): void {
dispatch(changeShowBitmapAction(event.target.checked));
@ -139,14 +145,15 @@ function AppearanceBlock(props: Props): JSX.Element {
colorBy,
opacity,
selectedOpacity,
blackBorders,
outlined,
outlineColor,
showBitmap,
showProjections,
collapseAppearance,
changeShapesColorBy,
changeShapesOpacity,
changeSelectedShapesOpacity,
changeShapesBlackBorders,
changeShapesOutlinedBorders,
changeShowBitmap,
changeShowProjections,
} = props;
@ -185,10 +192,22 @@ function AppearanceBlock(props: Props): JSX.Element {
max={100}
/>
<Checkbox
onChange={changeShapesBlackBorders}
checked={blackBorders}
onChange={(event: CheckboxChangeEvent) => {
changeShapesOutlinedBorders(event.target.checked, outlineColor);
}}
checked={outlined}
>
Black borders
Outlined borders
<ColorPicker
onChange={(color) => changeShapesOutlinedBorders(outlined, color)}
value={outlineColor}
placement='top'
resetVisible={false}
>
<Button type='link' shape='circle'>
<ColorizeIcon />
</Button>
</ColorPicker>
</Checkbox>
<Checkbox
onChange={changeShowBitmap}

@ -28,7 +28,11 @@ export default function CanvasContextMenu(props: Props): JSX.Element | null {
return ReactDOM.createPortal(
<div className='cvat-canvas-context-menu' style={{ top, left }}>
<ObjectItemContainer key={activatedStateID} clientID={activatedStateID} />
<ObjectItemContainer
key={activatedStateID}
clientID={activatedStateID}
initialCollapsed
/>
</div>,
window.document.body,
);

@ -42,7 +42,8 @@ interface Props {
opacity: number;
colorBy: ColorBy;
selectedOpacity: number;
blackBorders: boolean;
outlined: boolean;
outlineColor: string;
showBitmap: boolean;
showProjections: boolean;
grid: boolean;
@ -125,7 +126,8 @@ export default class CanvasWrapperComponent extends React.PureComponent<Props> {
opacity,
colorBy,
selectedOpacity,
blackBorders,
outlined,
outlineColor,
showBitmap,
frameData,
frameAngle,
@ -230,7 +232,8 @@ export default class CanvasWrapperComponent extends React.PureComponent<Props> {
}, { once: true });
}
if (prevProps.opacity !== opacity || prevProps.blackBorders !== blackBorders
if (prevProps.opacity !== opacity || prevProps.outlined !== outlined
|| prevProps.outlineColor !== outlineColor
|| prevProps.selectedOpacity !== selectedOpacity || prevProps.colorBy !== colorBy
) {
this.updateShapesView();
@ -602,7 +605,8 @@ export default class CanvasWrapperComponent extends React.PureComponent<Props> {
annotations,
opacity,
colorBy,
blackBorders,
outlined,
outlineColor,
} = this.props;
for (const state of annotations) {
@ -625,7 +629,7 @@ export default class CanvasWrapperComponent extends React.PureComponent<Props> {
}
(shapeView as any).instance.fill({ color: shapeColor, opacity: opacity / 100 });
(shapeView as any).instance.stroke({ color: blackBorders ? 'black' : shapeColor });
(shapeView as any).instance.stroke({ color: outlined ? outlineColor : shapeColor });
}
}
}

@ -12,7 +12,7 @@ interface Props {
listHeight: number;
statesHidden: boolean;
statesLocked: boolean;
statesCollapsed: boolean;
statesCollapsedAll: boolean;
statesOrdering: StatesOrdering;
sortedStatesID: number[];
switchLockAllShortcut: string;
@ -31,7 +31,7 @@ function ObjectListComponent(props: Props): JSX.Element {
listHeight,
statesHidden,
statesLocked,
statesCollapsed,
statesCollapsedAll,
statesOrdering,
sortedStatesID,
switchLockAllShortcut,
@ -50,7 +50,7 @@ function ObjectListComponent(props: Props): JSX.Element {
<ObjectListHeader
statesHidden={statesHidden}
statesLocked={statesLocked}
statesCollapsed={statesCollapsed}
statesCollapsed={statesCollapsedAll}
statesOrdering={statesOrdering}
switchLockAllShortcut={switchLockAllShortcut}
switchHiddenAllShortcut={switchHiddenAllShortcut}
@ -64,7 +64,11 @@ function ObjectListComponent(props: Props): JSX.Element {
/>
<div className='cvat-objects-sidebar-states-list'>
{ sortedStatesID.map((id: number): JSX.Element => (
<ObjectItemContainer key={id} clientID={id} />
<ObjectItemContainer
key={id}
clientID={id}
initialCollapsed={statesCollapsedAll}
/>
))}
</div>
</div>

@ -64,7 +64,8 @@ interface StateToProps {
opacity: number;
colorBy: ColorBy;
selectedOpacity: number;
blackBorders: boolean;
outlined: boolean;
outlineColor: string;
showBitmap: boolean;
showProjections: boolean;
grid: boolean;
@ -179,7 +180,8 @@ function mapStateToProps(state: CombinedState): StateToProps {
opacity,
colorBy,
selectedOpacity,
blackBorders,
outlined,
outlineColor,
showBitmap,
showProjections,
},
@ -204,7 +206,8 @@ function mapStateToProps(state: CombinedState): StateToProps {
opacity,
colorBy,
selectedOpacity,
blackBorders,
outlined,
outlineColor,
showBitmap,
showProjections,
grid,

@ -30,6 +30,7 @@ import { shift } from 'utils/math';
interface OwnProps {
clientID: number;
initialCollapsed: boolean;
}
interface StateToProps {
@ -101,7 +102,7 @@ function mapStateToProps(state: CombinedState, own: OwnProps): StateToProps {
.indexOf(own.clientID);
const collapsedState = typeof (statesCollapsed[own.clientID]) === 'undefined'
? true : statesCollapsed[own.clientID];
? own.initialCollapsed : statesCollapsed[own.clientID];
return {
objectState: states[index],

@ -30,7 +30,8 @@ interface StateToProps {
listHeight: number;
statesHidden: boolean;
statesLocked: boolean;
statesCollapsed: boolean;
statesCollapsedAll: boolean;
collapsedStates: Record<number, boolean>;
objectStates: any[];
annotationsFilters: string[];
colors: string[];
@ -62,6 +63,7 @@ function mapStateToProps(state: CombinedState): StateToProps {
filters: annotationsFilters,
filtersHistory: annotationsFiltersHistory,
collapsed,
collapsedAll,
activatedStateID,
zLayer: {
min: minZLayer,
@ -95,25 +97,23 @@ function mapStateToProps(state: CombinedState): StateToProps {
let statesHidden = true;
let statesLocked = true;
let statesCollapsed = true;
objectStates.forEach((objectState: any) => {
const { clientID, lock } = objectState;
const { lock } = objectState;
if (!lock) {
if (objectState.objectType !== ObjectType.TAG) {
statesHidden = statesHidden && objectState.hidden;
}
statesLocked = statesLocked && objectState.lock;
}
const stateCollapsed = clientID in collapsed ? collapsed[clientID] : true;
statesCollapsed = statesCollapsed && stateCollapsed;
});
return {
listHeight,
statesHidden,
statesLocked,
statesCollapsed,
statesCollapsedAll: collapsedAll,
collapsedStates: collapsed,
objectStates,
frameNumber,
jobInstance,

@ -67,6 +67,7 @@ const defaultState: AnnotationState = {
statuses: [],
},
collapsed: {},
collapsedAll: true,
states: [],
filters: [],
filtersHistory: JSON.parse(
@ -352,6 +353,7 @@ export default (state = defaultState, action: AnyAction): AnnotationState => {
} = action.payload;
const updatedCollapsedStates = { ...state.annotations.collapsed };
const totalStatesCount = state.annotations.states.length;
for (const objectState of states) {
updatedCollapsedStates[objectState.clientID] = collapsed;
}
@ -361,6 +363,8 @@ export default (state = defaultState, action: AnyAction): AnnotationState => {
annotations: {
...state.annotations,
collapsed: updatedCollapsedStates,
collapsedAll: states.length === totalStatesCount
? collapsed : state.annotations.collapsedAll,
},
};
}

@ -361,6 +361,7 @@ export interface AnnotationState {
activatedStateID: number | null;
activatedAttributeID: number | null;
collapsed: Record<number, boolean>;
collapsedAll: boolean;
states: any[];
filters: string[];
filtersHistory: string[];
@ -452,7 +453,8 @@ export interface ShapesSettingsState {
colorBy: ColorBy;
opacity: number;
selectedOpacity: number;
blackBorders: boolean;
outlined: boolean;
outlineColor: string;
showBitmap: boolean;
showProjections: boolean;
}

@ -21,7 +21,8 @@ const defaultState: SettingsState = {
colorBy: ColorBy.LABEL,
opacity: 3,
selectedOpacity: 30,
blackBorders: false,
outlined: false,
outlineColor: '#000000',
showBitmap: false,
showProjections: false,
},
@ -124,12 +125,13 @@ export default (state = defaultState, action: AnyAction): SettingsState => {
},
};
}
case SettingsActionTypes.CHANGE_SHAPES_BLACK_BORDERS: {
case SettingsActionTypes.CHANGE_SHAPES_OUTLINED_BORDERS: {
return {
...state,
shapes: {
...state.shapes,
blackBorders: action.payload.blackBorders,
outlined: action.payload.outlined,
outlineColor: action.payload.color,
},
};
}

Loading…
Cancel
Save