@abidibo/react-cam-roi 0.2.3 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -2
- package/dist/index.cjs.css +2 -0
- package/dist/index.cjs.css.map +1 -0
- package/dist/index.cjs.js +1582 -0
- package/dist/index.cjs.js.map +1 -0
- package/dist/index.esm.css +2 -0
- package/dist/index.esm.css.map +1 -0
- package/dist/index.esm.js +1576 -0
- package/dist/index.esm.js.map +1 -0
- package/package.json +17 -6
- package/dist/Components/BoolField/index.js +0 -13
- package/dist/Components/Button/index.js +0 -15
- package/dist/Components/EnumField/index.js +0 -16
- package/dist/Components/IconButton/index.js +0 -10
- package/dist/Components/Loader/index.js +0 -9
- package/dist/Components/Modal/index.js +0 -16
- package/dist/Components/NumberField/index.js +0 -13
- package/dist/Components/RoiEditor/Canvas.js +0 -30
- package/dist/Components/RoiEditor/ColorPicker.js +0 -12
- package/dist/Components/RoiEditor/Header.js +0 -14
- package/dist/Components/RoiEditor/Hooks.js +0 -328
- package/dist/Components/RoiEditor/ParameterField.js +0 -27
- package/dist/Components/RoiEditor/ParametersModalForm/index.js +0 -42
- package/dist/Components/RoiEditor/Polygon.js +0 -77
- package/dist/Components/RoiEditor/Polyline.js +0 -75
- package/dist/Components/RoiEditor/Rectangle.js +0 -73
- package/dist/Components/RoiEditor/RoisInfo.js +0 -43
- package/dist/Components/RoiEditor/ShapesList.js +0 -77
- package/dist/Components/RoiEditor/Toolbar.js +0 -27
- package/dist/Components/RoiEditor/TopBar.js +0 -21
- package/dist/Components/RoiEditor/Types.js +0 -23
- package/dist/Components/RoiEditor/Utils.js +0 -161
- package/dist/Components/RoiEditor/index.js +0 -99
- package/dist/Components/RoleField.js +0 -49
- package/dist/Components/TextField/index.js +0 -13
- package/dist/Components/Typography/index.js +0 -6
- package/dist/Icons/AnnotateIcon.js +0 -5
- package/dist/Icons/CloseIcon.js +0 -5
- package/dist/Icons/CopyIcon.js +0 -5
- package/dist/Icons/DeleteIcon.js +0 -5
- package/dist/Icons/EditIcon.js +0 -5
- package/dist/Icons/PointerIcon.js +0 -5
- package/dist/Icons/PolygonIcon.js +0 -5
- package/dist/Icons/PolylineIcon.js +0 -5
- package/dist/Icons/RectangleIcon.js +0 -5
- package/dist/Icons/SaveIcon.js +0 -5
- package/dist/Providers/EditorProvider.js +0 -29
- package/dist/Providers/UiProvider.js +0 -104
- package/dist/Types.js +0 -1
- package/dist/Utils/Dispatcher.js +0 -65
- package/dist/Utils/index.js +0 -16
- package/dist/index.js +0 -4
- /package/dist/{Components → types/Components}/BoolField/index.d.ts +0 -0
- /package/dist/{Components → types/Components}/Button/index.d.ts +0 -0
- /package/dist/{Components → types/Components}/EnumField/index.d.ts +0 -0
- /package/dist/{Components → types/Components}/IconButton/index.d.ts +0 -0
- /package/dist/{Components → types/Components}/Loader/index.d.ts +0 -0
- /package/dist/{Components → types/Components}/Modal/index.d.ts +0 -0
- /package/dist/{Components → types/Components}/NumberField/index.d.ts +0 -0
- /package/dist/{Components → types/Components}/RoiEditor/Canvas.d.ts +0 -0
- /package/dist/{Components → types/Components}/RoiEditor/ColorPicker.d.ts +0 -0
- /package/dist/{Components → types/Components}/RoiEditor/Header.d.ts +0 -0
- /package/dist/{Components → types/Components}/RoiEditor/Hooks.d.ts +0 -0
- /package/dist/{Components → types/Components}/RoiEditor/ParameterField.d.ts +0 -0
- /package/dist/{Components → types/Components}/RoiEditor/ParametersModalForm/index.d.ts +0 -0
- /package/dist/{Components → types/Components}/RoiEditor/Polygon.d.ts +0 -0
- /package/dist/{Components → types/Components}/RoiEditor/Polyline.d.ts +0 -0
- /package/dist/{Components → types/Components}/RoiEditor/Rectangle.d.ts +0 -0
- /package/dist/{Components → types/Components}/RoiEditor/RoisInfo.d.ts +0 -0
- /package/dist/{Components → types/Components}/RoiEditor/ShapesList.d.ts +0 -0
- /package/dist/{Components → types/Components}/RoiEditor/Toolbar.d.ts +0 -0
- /package/dist/{Components → types/Components}/RoiEditor/TopBar.d.ts +0 -0
- /package/dist/{Components → types/Components}/RoiEditor/Types.d.ts +0 -0
- /package/dist/{Components → types/Components}/RoiEditor/Utils.d.ts +0 -0
- /package/dist/{Components → types/Components}/RoiEditor/index.d.ts +0 -0
- /package/dist/{Components → types/Components}/RoleField.d.ts +0 -0
- /package/dist/{Components → types/Components}/TextField/index.d.ts +0 -0
- /package/dist/{Components → types/Components}/Typography/index.d.ts +0 -0
- /package/dist/{Icons → types/Icons}/AnnotateIcon.d.ts +0 -0
- /package/dist/{Icons → types/Icons}/CloseIcon.d.ts +0 -0
- /package/dist/{Icons → types/Icons}/CopyIcon.d.ts +0 -0
- /package/dist/{Icons → types/Icons}/DeleteIcon.d.ts +0 -0
- /package/dist/{Icons → types/Icons}/EditIcon.d.ts +0 -0
- /package/dist/{Icons → types/Icons}/PointerIcon.d.ts +0 -0
- /package/dist/{Icons → types/Icons}/PolygonIcon.d.ts +0 -0
- /package/dist/{Icons → types/Icons}/PolylineIcon.d.ts +0 -0
- /package/dist/{Icons → types/Icons}/RectangleIcon.d.ts +0 -0
- /package/dist/{Icons → types/Icons}/SaveIcon.d.ts +0 -0
- /package/dist/{Providers → types/Providers}/EditorProvider.d.ts +0 -0
- /package/dist/{Providers → types/Providers}/UiProvider.d.ts +0 -0
- /package/dist/{Types.d.ts → types/Types.d.ts} +0 -0
- /package/dist/{Utils → types/Utils}/Dispatcher.d.ts +0 -0
- /package/dist/{Utils → types/Utils}/index.d.ts +0 -0
- /package/dist/{index.d.ts → types/index.d.ts} +0 -0
@@ -1,77 +0,0 @@
|
|
1
|
-
import * as fabric from 'fabric';
|
2
|
-
import { v4 as uuidv4 } from 'uuid';
|
3
|
-
import Dispatcher from '../../Utils/Dispatcher';
|
4
|
-
const addPoint = (event, canvas, color, points, setPoints, lines, setLines) => {
|
5
|
-
const pointer = canvas.getScenePoint(event.e);
|
6
|
-
const newPoint = { x: pointer.x, y: pointer.y };
|
7
|
-
const newPolygonPoints = [...points, newPoint];
|
8
|
-
setPoints(newPolygonPoints);
|
9
|
-
if (newPolygonPoints.length > 0) {
|
10
|
-
const line = new fabric.Line([
|
11
|
-
newPolygonPoints[newPolygonPoints.length - 1].x,
|
12
|
-
newPolygonPoints[newPolygonPoints.length - 1].y,
|
13
|
-
pointer.x,
|
14
|
-
pointer.y,
|
15
|
-
], {
|
16
|
-
stroke: color,
|
17
|
-
strokeWidth: 2,
|
18
|
-
strokeUniform: true,
|
19
|
-
selectable: false,
|
20
|
-
hasControls: false,
|
21
|
-
});
|
22
|
-
canvas.add(line);
|
23
|
-
setLines([...lines, line]);
|
24
|
-
}
|
25
|
-
};
|
26
|
-
export const handleMouseDownPolygon = (event, canvas, activeColor, setIsDrawing, points, setPoints, lines, setLines) => {
|
27
|
-
setIsDrawing(true);
|
28
|
-
addPoint(event, canvas, activeColor, points, setPoints, lines, setLines);
|
29
|
-
};
|
30
|
-
export const handleMouseMovePolygon = (event, canvas, isDrawing, lines) => {
|
31
|
-
if (isDrawing && lines.length > 0) {
|
32
|
-
const pointer = canvas.getScenePoint(event.e);
|
33
|
-
lines[lines.length - 1].set({ x2: pointer.x, y2: pointer.y });
|
34
|
-
canvas.renderAll();
|
35
|
-
}
|
36
|
-
};
|
37
|
-
export const handleDoubleClickPolygon = (editorId, canvas, activeColor, setIsDrawing, points, setPoints, lines, setLines) => {
|
38
|
-
if (points.length > 2) {
|
39
|
-
const id = uuidv4();
|
40
|
-
const polygon = new fabric.Polygon(points, {
|
41
|
-
fill: 'transparent',
|
42
|
-
stroke: activeColor,
|
43
|
-
strokeWidth: 2,
|
44
|
-
selectable: false,
|
45
|
-
hasControls: true,
|
46
|
-
hoverCursor: 'default',
|
47
|
-
// @ts-expect-error id is not included in types but the property is added and it works
|
48
|
-
id,
|
49
|
-
});
|
50
|
-
canvas.add(polygon);
|
51
|
-
Dispatcher.emit(`canvas:${editorId}:shapeAdded`, { id, type: "polygon" /* ToolEnum.Polygon */, shape: polygon });
|
52
|
-
setPoints([]);
|
53
|
-
for (const line of lines) {
|
54
|
-
canvas.remove(line); // Remove temporary lines
|
55
|
-
}
|
56
|
-
setLines([]);
|
57
|
-
setIsDrawing(false);
|
58
|
-
}
|
59
|
-
};
|
60
|
-
export const copyPolygon = (editorId, canvas, polygon) => {
|
61
|
-
const id = uuidv4();
|
62
|
-
const copy = new fabric.Polygon(polygon.points, {
|
63
|
-
top: polygon.top + 10,
|
64
|
-
left: polygon.left + 10,
|
65
|
-
fill: 'transparent',
|
66
|
-
stroke: polygon.stroke,
|
67
|
-
strokeWidth: polygon.strokeWidth,
|
68
|
-
selectable: false,
|
69
|
-
hasControls: true,
|
70
|
-
hoverCursor: 'default',
|
71
|
-
// @ts-expect-error id is not included in types but the property is added and it works
|
72
|
-
id,
|
73
|
-
});
|
74
|
-
canvas.add(copy);
|
75
|
-
Dispatcher.emit(`canvas:${editorId}:shapeAdded`, { id, type: "polygon" /* ToolEnum.Polygon */, shape: copy });
|
76
|
-
return copy;
|
77
|
-
};
|
@@ -1,75 +0,0 @@
|
|
1
|
-
import * as fabric from 'fabric';
|
2
|
-
import { v4 as uuidv4 } from 'uuid';
|
3
|
-
import Dispatcher from '../../Utils/Dispatcher';
|
4
|
-
const addPoint = (event, canvas, color, points, setPoints, lines, setLines) => {
|
5
|
-
const pointer = canvas.getScenePoint(event.e);
|
6
|
-
const newPoint = { x: pointer.x, y: pointer.y };
|
7
|
-
const newPolylinePoints = [...points, newPoint];
|
8
|
-
setPoints(newPolylinePoints);
|
9
|
-
if (newPolylinePoints.length > 0) {
|
10
|
-
const line = new fabric.Line([
|
11
|
-
newPolylinePoints[newPolylinePoints.length - 1].x,
|
12
|
-
newPolylinePoints[newPolylinePoints.length - 1].y,
|
13
|
-
pointer.x,
|
14
|
-
pointer.y,
|
15
|
-
], {
|
16
|
-
stroke: color,
|
17
|
-
strokeWidth: 2,
|
18
|
-
strokeUniform: true,
|
19
|
-
selectable: false,
|
20
|
-
hasControls: false,
|
21
|
-
});
|
22
|
-
canvas.add(line);
|
23
|
-
setLines([...lines, line]);
|
24
|
-
}
|
25
|
-
};
|
26
|
-
export const handleMouseDownPolyline = (event, canvas, activeColor, setIsDrawing, points, setPoints, lines, setLines) => {
|
27
|
-
setIsDrawing(true);
|
28
|
-
addPoint(event, canvas, activeColor, points, setPoints, lines, setLines);
|
29
|
-
};
|
30
|
-
export const handleMouseMovePolyline = (event, canvas, isDrawing, lines) => {
|
31
|
-
if (isDrawing && lines.length > 0) {
|
32
|
-
const pointer = canvas.getScenePoint(event.e);
|
33
|
-
lines[lines.length - 1].set({ x2: pointer.x, y2: pointer.y });
|
34
|
-
canvas.renderAll();
|
35
|
-
}
|
36
|
-
};
|
37
|
-
export const handleDoubleClickPolyline = (editorId, canvas, activeColor, setIsDrawing, points, setPoints, lines, setLines) => {
|
38
|
-
if (points.length > 2) {
|
39
|
-
const id = uuidv4();
|
40
|
-
const polyline = new fabric.Polyline(points, {
|
41
|
-
fill: 'transparent',
|
42
|
-
stroke: activeColor,
|
43
|
-
strokeWidth: 2,
|
44
|
-
selectable: false,
|
45
|
-
hasControls: true,
|
46
|
-
lockRotation: false,
|
47
|
-
id,
|
48
|
-
});
|
49
|
-
canvas.add(polyline);
|
50
|
-
Dispatcher.emit(`canvas:${editorId}:shapeAdded`, { id, type: "polyline" /* ToolEnum.Polyline */, shape: polyline });
|
51
|
-
setPoints([]);
|
52
|
-
for (const line of lines) {
|
53
|
-
canvas.remove(line); // Remove temporary lines
|
54
|
-
}
|
55
|
-
setLines([]);
|
56
|
-
setIsDrawing(false);
|
57
|
-
}
|
58
|
-
};
|
59
|
-
export const copyPolyline = (editorId, canvas, polyline) => {
|
60
|
-
const id = uuidv4();
|
61
|
-
const copy = new fabric.Polyline(polyline.points, {
|
62
|
-
top: polyline.top + 10,
|
63
|
-
left: polyline.left + 10,
|
64
|
-
fill: 'transparent',
|
65
|
-
stroke: polyline.stroke,
|
66
|
-
strokeWidth: polyline.strokeWidth,
|
67
|
-
selectable: false,
|
68
|
-
hasControls: true,
|
69
|
-
hoverCursor: 'default',
|
70
|
-
id,
|
71
|
-
});
|
72
|
-
canvas.add(copy);
|
73
|
-
Dispatcher.emit(`canvas:${editorId}:shapeAdded`, { id, type: "polyline" /* ToolEnum.Polyline */, shape: copy });
|
74
|
-
return copy;
|
75
|
-
};
|
@@ -1,73 +0,0 @@
|
|
1
|
-
import * as fabric from 'fabric';
|
2
|
-
import { v4 as uuidv4 } from 'uuid';
|
3
|
-
import Dispatcher from '../../Utils/Dispatcher';
|
4
|
-
export const handleMouseDownRect = (event, canvas, activeColor, setOriginX, setOriginY, setShape, setIsDrawing) => {
|
5
|
-
const pointer = canvas.getScenePoint(event.e);
|
6
|
-
setOriginX(pointer.x);
|
7
|
-
setOriginY(pointer.y);
|
8
|
-
const id = uuidv4();
|
9
|
-
const newRectangle = new fabric.Rect({
|
10
|
-
left: pointer.x,
|
11
|
-
top: pointer.y,
|
12
|
-
originX: 'left',
|
13
|
-
originY: 'top',
|
14
|
-
width: 0,
|
15
|
-
height: 0,
|
16
|
-
fill: 'transparent',
|
17
|
-
stroke: activeColor,
|
18
|
-
strokeWidth: 2,
|
19
|
-
strokeUniform: true,
|
20
|
-
selectable: false,
|
21
|
-
hasControls: true,
|
22
|
-
hoverCursor: 'default',
|
23
|
-
id,
|
24
|
-
});
|
25
|
-
canvas.add(newRectangle);
|
26
|
-
setShape(newRectangle);
|
27
|
-
setIsDrawing(true);
|
28
|
-
};
|
29
|
-
export const handleMouseMoveRect = (event, canvas, originX, originY, shape, isDrawing) => {
|
30
|
-
if (isDrawing && shape) {
|
31
|
-
const pointer = canvas.getScenePoint(event.e);
|
32
|
-
shape.set({
|
33
|
-
width: Math.abs(originX - pointer.x),
|
34
|
-
height: Math.abs(originY - pointer.y),
|
35
|
-
});
|
36
|
-
if (originX > pointer.x) {
|
37
|
-
shape.set({ left: pointer.x });
|
38
|
-
}
|
39
|
-
if (originY > pointer.y) {
|
40
|
-
shape.set({ top: pointer.y });
|
41
|
-
}
|
42
|
-
canvas.renderAll();
|
43
|
-
}
|
44
|
-
};
|
45
|
-
export const handleMouseUpRect = (editorId, canvas, setIsDrawing, shape, setShape) => {
|
46
|
-
setIsDrawing(false);
|
47
|
-
shape.setCoords();
|
48
|
-
Dispatcher.emit(`canvas:${editorId}:shapeAdded`, { id: shape.id, type: "rect" /* ToolEnum.Rectangle */, shape });
|
49
|
-
setShape(null);
|
50
|
-
canvas.defaultCursor = 'default';
|
51
|
-
};
|
52
|
-
export const copyRectangle = (editorId, canvas, rectangle) => {
|
53
|
-
const id = uuidv4();
|
54
|
-
const copy = new fabric.Rect({
|
55
|
-
left: rectangle.left + 10,
|
56
|
-
top: rectangle.top + 10,
|
57
|
-
originX: 'left',
|
58
|
-
originY: 'top',
|
59
|
-
width: rectangle.width,
|
60
|
-
height: rectangle.height,
|
61
|
-
fill: 'transparent',
|
62
|
-
stroke: rectangle.stroke,
|
63
|
-
strokeWidth: rectangle.strokeWidth,
|
64
|
-
strokeUniform: true,
|
65
|
-
selectable: false,
|
66
|
-
hasControls: true,
|
67
|
-
hoverCursor: 'default',
|
68
|
-
id,
|
69
|
-
});
|
70
|
-
canvas.add(copy);
|
71
|
-
Dispatcher.emit(`canvas:${editorId}:shapeAdded`, { id, type: "rect" /* ToolEnum.Rectangle */, shape: copy });
|
72
|
-
return copy;
|
73
|
-
};
|
@@ -1,43 +0,0 @@
|
|
1
|
-
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
2
|
-
import { useContext } from 'react';
|
3
|
-
import { useEditorContext } from '../../Providers/EditorProvider';
|
4
|
-
import { UiContext } from '../../Providers/UiProvider';
|
5
|
-
import { formatString } from '../../Utils';
|
6
|
-
import { OperatorEnum } from './Types';
|
7
|
-
const RoisInfo = () => {
|
8
|
-
var _a;
|
9
|
-
const { strings, Typography } = useContext(UiContext);
|
10
|
-
const { configuration } = useEditorContext();
|
11
|
-
if (!((_a = configuration.rois) === null || _a === void 0 ? void 0 : _a.length))
|
12
|
-
return null;
|
13
|
-
return (_jsxs("div", { children: [_jsxs(Typography, { component: "div", children: [strings.roisToBeDrawn, ":"] }), _jsx("ul", { children: configuration.rois.map((r) => {
|
14
|
-
var _a, _b;
|
15
|
-
let rule;
|
16
|
-
const data = {
|
17
|
-
role: r.label,
|
18
|
-
type: r.type,
|
19
|
-
threshold: (_a = r.multiplicity) === null || _a === void 0 ? void 0 : _a.threshold,
|
20
|
-
};
|
21
|
-
switch ((_b = r.multiplicity) === null || _b === void 0 ? void 0 : _b.operator) {
|
22
|
-
case OperatorEnum.Eq:
|
23
|
-
rule = formatString(strings.roiMultiplicityEqRule, data);
|
24
|
-
break;
|
25
|
-
case OperatorEnum.Lt:
|
26
|
-
rule = formatString(strings.roiMultiplicityLtRule, data);
|
27
|
-
break;
|
28
|
-
case OperatorEnum.Lte:
|
29
|
-
rule = formatString(strings.roiMultiplicityLteRule, data);
|
30
|
-
break;
|
31
|
-
case OperatorEnum.Gt:
|
32
|
-
rule = formatString(strings.roiMultiplicityGtRule, data);
|
33
|
-
break;
|
34
|
-
case OperatorEnum.Gte:
|
35
|
-
rule = formatString(strings.roiMultiplicityGteRule, data);
|
36
|
-
break;
|
37
|
-
default:
|
38
|
-
rule = formatString(strings.roiMultiplicityNoRule, data);
|
39
|
-
}
|
40
|
-
return (_jsx("li", { children: _jsx(Typography, { children: rule }) }, r.role));
|
41
|
-
}) })] }));
|
42
|
-
};
|
43
|
-
export default RoisInfo;
|
@@ -1,77 +0,0 @@
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
2
|
-
import { useContext, useEffect, useState } from 'react';
|
3
|
-
import { useEditorContext } from '../../Providers/EditorProvider';
|
4
|
-
import { UiContext } from '../../Providers/UiProvider';
|
5
|
-
import { css } from '../../Utils';
|
6
|
-
import Dispatcher from '../../Utils/Dispatcher';
|
7
|
-
import ParametersModalForm from './ParametersModalForm';
|
8
|
-
import styles from './ShapesList.module.css';
|
9
|
-
const ShapesList = () => {
|
10
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
11
|
-
const { strings, Typography, IconButton, DeleteIcon, AnnotateIcon, CopyIcon, themeMode } = useContext(UiContext);
|
12
|
-
const { shapes, removeShape, configuration, metadata, setMetadata, addShape, editorId } = useEditorContext();
|
13
|
-
const [selected, setSelected] = useState([]);
|
14
|
-
const [form, setForm] = useState({
|
15
|
-
isOpen: false,
|
16
|
-
shapeId: '',
|
17
|
-
type: null,
|
18
|
-
shape: null,
|
19
|
-
});
|
20
|
-
// open metadata form immediately after drawing the shape
|
21
|
-
useEffect(() => {
|
22
|
-
const openForm = (_, { id, type, shape }) => {
|
23
|
-
setForm({ isOpen: true, shapeId: id, type, shape });
|
24
|
-
};
|
25
|
-
Dispatcher.register(`canvas:${editorId}:shapeAdded`, openForm);
|
26
|
-
return () => {
|
27
|
-
Dispatcher.unregister(`canvas:${editorId}:shapeAdded`, openForm);
|
28
|
-
};
|
29
|
-
}, [editorId]);
|
30
|
-
useEffect(() => {
|
31
|
-
const setSelectedShapes = (_, event) => { var _a; return setSelected((_a = event === null || event === void 0 ? void 0 : event.map((s) => s.id)) !== null && _a !== void 0 ? _a : []); };
|
32
|
-
Dispatcher.register(`canvas:${editorId}:shapeSelected`, setSelectedShapes);
|
33
|
-
return () => {
|
34
|
-
Dispatcher.unregister(`canvas:${editorId}:shapeSelected`, setSelectedShapes);
|
35
|
-
};
|
36
|
-
}, [shapes, editorId]);
|
37
|
-
const handleCopyShape = (id) => (evt) => {
|
38
|
-
evt.stopPropagation();
|
39
|
-
Dispatcher.emit(`canvas:${editorId}:copyShape`, id);
|
40
|
-
};
|
41
|
-
const handleRemoveShape = (id) => () => {
|
42
|
-
Dispatcher.emit(`canvas:${editorId}:removeShape`, id);
|
43
|
-
removeShape(id);
|
44
|
-
};
|
45
|
-
const handleSelectShape = (id) => () => {
|
46
|
-
Dispatcher.emit(`canvas:${editorId}:selectShape`, id);
|
47
|
-
};
|
48
|
-
const handleEditShapeMetadata = (id) => () => {
|
49
|
-
setForm({ isOpen: true, shapeId: id, type: null, shape: null });
|
50
|
-
};
|
51
|
-
const handleSubmitMetadata = (shapeId) => (data, properties) => {
|
52
|
-
// if in creation mode, add the shape
|
53
|
-
if (form.type !== null) {
|
54
|
-
addShape(shapeId, form.type, form.shape);
|
55
|
-
}
|
56
|
-
setMetadata(Object.assign(Object.assign({}, metadata), { rois: [...metadata.rois.filter((r) => r.id !== shapeId), Object.assign({ id: shapeId, parameters: data }, properties)] }));
|
57
|
-
setForm({ isOpen: false, shapeId: '', type: null, shape: null });
|
58
|
-
};
|
59
|
-
const handleCloseMetadataForm = () => {
|
60
|
-
// if in creation mode do not add shape and delete shape from canvas
|
61
|
-
if (form.type !== null) {
|
62
|
-
Dispatcher.emit(`canvas:${editorId}:removeShape`, form.shapeId);
|
63
|
-
}
|
64
|
-
setForm({ isOpen: false, shapeId: '', type: null, shape: null });
|
65
|
-
};
|
66
|
-
const iconColor = themeMode === 'light' ? 'black' : 'white';
|
67
|
-
return (_jsxs(_Fragment, { children: [_jsxs("table", { className: css('shapes-table', styles, themeMode), children: [Object.keys(shapes).length > 0 && (_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { children: _jsx(Typography, { style: { fontWeight: 'bold' }, children: strings.name }) }), _jsx("th", { children: _jsx(Typography, { style: { fontWeight: 'bold' }, children: strings.role }) }), _jsx("th", { children: _jsx(Typography, { style: { fontWeight: 'bold' }, children: strings.type }) }), _jsx("th", {})] }) })), _jsx("tbody", { children: Object.keys(shapes).map((id, idx) => {
|
68
|
-
var _a;
|
69
|
-
const m = metadata.rois.find((roi) => roi.id === id);
|
70
|
-
return (_jsxs("tr", { onClick: handleSelectShape(id), className: selected.indexOf(id) > -1
|
71
|
-
? css('shapes-row-selected', styles, themeMode)
|
72
|
-
: idx % 2 === 0
|
73
|
-
? css('shapes-row-even', styles, themeMode)
|
74
|
-
: css('shapes-row-odd', styles, themeMode), children: [_jsx("td", { children: _jsxs("div", { className: styles.shapesTableName, children: [_jsx("div", { className: styles.shapesTableColor, style: { backgroundColor: shapes[id].shape.stroke } }), _jsx(Typography, { children: m === null || m === void 0 ? void 0 : m.name })] }) }), _jsx("td", { children: _jsx(Typography, { children: (_a = configuration.rois.find(r => r.role === (m === null || m === void 0 ? void 0 : m.role))) === null || _a === void 0 ? void 0 : _a.label }) }), _jsx("td", { children: _jsx(Typography, { children: strings[shapes[id].type] }) }), _jsxs("td", { children: [_jsx(IconButton, { onClick: handleCopyShape(id), children: _jsx(CopyIcon, { color: iconColor }) }), _jsx(IconButton, { onClick: handleEditShapeMetadata(id), children: _jsx(AnnotateIcon, { color: iconColor }) }), _jsx(IconButton, { onClick: handleRemoveShape(id), children: _jsx(DeleteIcon, { color: iconColor }) })] })] }, id));
|
75
|
-
}) })] }), form.isOpen && (_jsx(ParametersModalForm, { shapeType: form.type || shapes[form.shapeId].type, shapeName: (_b = (_a = metadata.rois.find((roi) => roi.id === form.shapeId)) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : '', shapeRole: (_d = (_c = metadata.rois.find((roi) => roi.id === form.shapeId)) === null || _c === void 0 ? void 0 : _c.role) !== null && _d !== void 0 ? _d : '', shapeId: form.shapeId, parameters: (_f = (_e = configuration.rois.find((roi) => roi.type === (form.type || shapes[form.shapeId].type))) === null || _e === void 0 ? void 0 : _e.parameters) !== null && _f !== void 0 ? _f : [], data: (_k = (_h = (_g = metadata.rois.find((roi) => roi.id === form.shapeId)) === null || _g === void 0 ? void 0 : _g.parameters) !== null && _h !== void 0 ? _h : (_j = configuration.rois.find((roi) => roi.type === (form.type || shapes[form.shapeId].type))) === null || _j === void 0 ? void 0 : _j.parameters) !== null && _k !== void 0 ? _k : [], title: strings.shapeParametersMetadata, onClose: handleCloseMetadataForm, onSubmit: handleSubmitMetadata(form.shapeId) }))] }));
|
76
|
-
};
|
77
|
-
export default ShapesList;
|
@@ -1,27 +0,0 @@
|
|
1
|
-
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
2
|
-
import { useContext } from 'react';
|
3
|
-
import PointerIcon from '../../Icons/PointerIcon';
|
4
|
-
import PolygonIcon from '../../Icons/PolygonIcon';
|
5
|
-
import PolylineIcon from '../../Icons/PolylineIcon';
|
6
|
-
import RectangleIcon from '../../Icons/RectangleIcon';
|
7
|
-
import { useEditorContext } from '../../Providers/EditorProvider';
|
8
|
-
import { UiContext } from '../../Providers/UiProvider';
|
9
|
-
import { css } from '../../Utils';
|
10
|
-
import ColorPicker from './ColorPicker';
|
11
|
-
import styles from './Toolbar.module.css';
|
12
|
-
import { canDrawShape, enableRois } from './Utils';
|
13
|
-
const Toolbar = () => {
|
14
|
-
var _a;
|
15
|
-
const { IconButton, themeMode, primaryColor, Typography, strings } = useContext(UiContext);
|
16
|
-
const { activeTool, setActiveTool, configuration, shapes } = useEditorContext();
|
17
|
-
const iconColor = (tool) => (tool === activeTool ? primaryColor : themeMode === 'light' ? 'black' : 'white');
|
18
|
-
const setTool = (tool) => () => setActiveTool(tool);
|
19
|
-
const hideForbiddenTools = (_a = configuration.options) === null || _a === void 0 ? void 0 : _a.hideForbiddenTools;
|
20
|
-
const polylineEnabled = configuration.rois.find((r) => r.type === "polyline" /* ToolEnum.Polyline */) &&
|
21
|
-
canDrawShape(configuration, "polyline" /* ToolEnum.Polyline */, shapes);
|
22
|
-
const polygonEnabled = configuration.rois.find((r) => r.type === "polygon" /* ToolEnum.Polygon */) && canDrawShape(configuration, "polygon" /* ToolEnum.Polygon */, shapes);
|
23
|
-
const rectangleEnabled = configuration.rois.find((r) => r.type === "rect" /* ToolEnum.Rectangle */) &&
|
24
|
-
canDrawShape(configuration, "rect" /* ToolEnum.Rectangle */, shapes);
|
25
|
-
return (_jsxs(_Fragment, { children: [_jsx("div", { className: css('toolbar', styles, themeMode), children: enableRois(configuration) && (_jsxs(_Fragment, { children: [_jsx(IconButton, { onClick: setTool("pointer" /* ToolEnum.Pointer */), children: _jsx(PointerIcon, { color: iconColor("pointer" /* ToolEnum.Pointer */) }) }), (!hideForbiddenTools || polylineEnabled) && (_jsx(IconButton, { onClick: setTool("polyline" /* ToolEnum.Polyline */), disabled: !polylineEnabled, children: _jsx(PolylineIcon, { color: iconColor("polyline" /* ToolEnum.Polyline */) }) })), (!hideForbiddenTools || polygonEnabled) && (_jsx(IconButton, { onClick: setTool("polygon" /* ToolEnum.Polygon */), disabled: !polygonEnabled, children: _jsx(PolygonIcon, { color: iconColor("polygon" /* ToolEnum.Polygon */) }) })), (!hideForbiddenTools || rectangleEnabled) && (_jsx(IconButton, { onClick: setTool("rect" /* ToolEnum.Rectangle */), disabled: !rectangleEnabled, children: _jsx(RectangleIcon, { color: iconColor("rect" /* ToolEnum.Rectangle */) }) })), _jsx(ColorPicker, { style: { marginLeft: 'auto', marginRight: '.5rem' } })] })) }), enableRois(configuration) && (_jsx("div", { className: css('toolbar-helper', styles, themeMode), children: _jsxs(Typography, { children: [strings[activeTool], ": ", strings[`${activeTool}HelpText`]] }) }))] }));
|
26
|
-
};
|
27
|
-
export default Toolbar;
|
@@ -1,21 +0,0 @@
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
2
|
-
import { useContext, useState } from 'react';
|
3
|
-
import { useEditorContext } from '../../Providers/EditorProvider';
|
4
|
-
import { UiContext } from '../../Providers/UiProvider';
|
5
|
-
import { css } from '../../Utils';
|
6
|
-
import { enableMainMetadata } from './Utils';
|
7
|
-
import SaveIcon from '../../Icons/SaveIcon';
|
8
|
-
import ParametersModalForm from './ParametersModalForm';
|
9
|
-
import styles from './TopBar.module.css';
|
10
|
-
const TopBar = () => {
|
11
|
-
const { themeMode, AnnotateIcon, Button, primaryFgColor, strings } = useContext(UiContext);
|
12
|
-
const { configuration, onSubmit, metadata, setMetadata } = useEditorContext();
|
13
|
-
const [form, setForm] = useState({ isOpen: false });
|
14
|
-
const iconColor = themeMode === 'light' ? 'black' : 'white';
|
15
|
-
const handleSubmitMetadata = (data) => {
|
16
|
-
setMetadata(Object.assign(Object.assign({}, metadata), { parameters: data }));
|
17
|
-
setForm({ isOpen: false });
|
18
|
-
};
|
19
|
-
return (_jsxs("div", { className: css('top-bar', styles, themeMode), children: [enableMainMetadata(configuration) && (_jsxs(Button, { onClick: () => setForm({ isOpen: true }), children: [_jsx(AnnotateIcon, { color: iconColor }), " ", strings.mainParametersMetadata] })), _jsxs(Button, { primary: true, onClick: onSubmit, children: [_jsx(SaveIcon, { color: primaryFgColor }), " ", strings.save] }), form.isOpen && (_jsx(ParametersModalForm, { parameters: configuration.parameters, data: metadata.parameters, title: strings.mainParametersMetadata, onClose: () => setForm({ isOpen: false }), onSubmit: handleSubmitMetadata }))] }));
|
20
|
-
};
|
21
|
-
export default TopBar;
|
@@ -1,23 +0,0 @@
|
|
1
|
-
export var DataTypeEnum;
|
2
|
-
(function (DataTypeEnum) {
|
3
|
-
DataTypeEnum["Integer"] = "int";
|
4
|
-
DataTypeEnum["Float"] = "float";
|
5
|
-
DataTypeEnum["String"] = "string";
|
6
|
-
DataTypeEnum["Boolean"] = "bool";
|
7
|
-
})(DataTypeEnum || (DataTypeEnum = {}));
|
8
|
-
export var OperatorEnum;
|
9
|
-
(function (OperatorEnum) {
|
10
|
-
OperatorEnum["Lt"] = "lt";
|
11
|
-
OperatorEnum["Lte"] = "lte";
|
12
|
-
OperatorEnum["Gt"] = "gt";
|
13
|
-
OperatorEnum["Gte"] = "gte";
|
14
|
-
OperatorEnum["Eq"] = "eq";
|
15
|
-
})(OperatorEnum || (OperatorEnum = {}));
|
16
|
-
export var UpdateEventType;
|
17
|
-
(function (UpdateEventType) {
|
18
|
-
UpdateEventType["AddRoi"] = "AddRoi";
|
19
|
-
UpdateEventType["RemoveRoi"] = "RemoveRoi";
|
20
|
-
UpdateEventType["UpdateRoi"] = "UpdateRoi";
|
21
|
-
UpdateEventType["UpdateRoiParameters"] = "UpdateRoiParameters";
|
22
|
-
UpdateEventType["UpdateMainParameters"] = "UpdateMainParameters";
|
23
|
-
})(UpdateEventType || (UpdateEventType = {}));
|
@@ -1,161 +0,0 @@
|
|
1
|
-
import { abs2Perc, formatString } from '../../Utils';
|
2
|
-
import { OperatorEnum, } from './Types';
|
3
|
-
export const notify = {
|
4
|
-
info: (message) => alert(`Info: ${message}`),
|
5
|
-
warn: (message) => alert(`Warning: ${message}`),
|
6
|
-
error: (message) => alert(`Error: ${message}`),
|
7
|
-
success: (message) => alert(`Success: ${message}`),
|
8
|
-
};
|
9
|
-
export const enableRois = (configuration) => {
|
10
|
-
return configuration.rois.length > 0;
|
11
|
-
};
|
12
|
-
export const enableMainMetadata = (configuration) => {
|
13
|
-
return configuration.parameters.length > 0;
|
14
|
-
};
|
15
|
-
export const canDrawShape = (configuration, shapeType, shapes, notify, message) => {
|
16
|
-
const rules = configuration.rois.filter((roi) => roi.type === shapeType);
|
17
|
-
let currentShapeCount = Object.values(shapes).filter((s) => s.type === shapeType).length;
|
18
|
-
for (let i = 0; i < rules.length; i++) {
|
19
|
-
const rule = rules[i];
|
20
|
-
if (rule.multiplicity) {
|
21
|
-
switch (rule.multiplicity.operator) {
|
22
|
-
case OperatorEnum.Eq:
|
23
|
-
case OperatorEnum.Lte:
|
24
|
-
if (currentShapeCount < rule.multiplicity.threshold) {
|
25
|
-
return true;
|
26
|
-
}
|
27
|
-
currentShapeCount -= rule.multiplicity.threshold;
|
28
|
-
break;
|
29
|
-
case OperatorEnum.Lt:
|
30
|
-
if (currentShapeCount < rule.multiplicity.threshold - 1) {
|
31
|
-
return true;
|
32
|
-
}
|
33
|
-
currentShapeCount -= rule.multiplicity.threshold;
|
34
|
-
break;
|
35
|
-
default:
|
36
|
-
return true;
|
37
|
-
}
|
38
|
-
}
|
39
|
-
}
|
40
|
-
if (notify) {
|
41
|
-
notify.warn(message || '');
|
42
|
-
}
|
43
|
-
return false;
|
44
|
-
};
|
45
|
-
export const validateParametersForm = (parameters, fields, setErrors) => {
|
46
|
-
const err = {};
|
47
|
-
parameters.forEach((p) => {
|
48
|
-
if (p.required && isEmpty(fields[p.codename])) {
|
49
|
-
err[p.codename] = 'requiredField';
|
50
|
-
}
|
51
|
-
});
|
52
|
-
if (Object.keys(err).length > 0) {
|
53
|
-
setErrors(err);
|
54
|
-
return false;
|
55
|
-
}
|
56
|
-
return true;
|
57
|
-
};
|
58
|
-
const isEmpty = (v) => {
|
59
|
-
if (typeof v === 'string') {
|
60
|
-
return v.length === 0;
|
61
|
-
}
|
62
|
-
if (Array.isArray(v)) {
|
63
|
-
return v.length === 0;
|
64
|
-
}
|
65
|
-
return v === null || v === undefined;
|
66
|
-
};
|
67
|
-
export const validate = (configuration, shapes, metadata, strings) => {
|
68
|
-
const errors = [];
|
69
|
-
// check main parameters
|
70
|
-
if (configuration.parameters.length) {
|
71
|
-
if (metadata.parameters.find((p) => { var _a; return ((_a = configuration.parameters.find((p2) => p2.codename === p.codename)) === null || _a === void 0 ? void 0 : _a.required) && isEmpty(p.value); })) {
|
72
|
-
errors.push(strings.missingRequiredValuesInMainParameters);
|
73
|
-
}
|
74
|
-
}
|
75
|
-
// check rois number
|
76
|
-
configuration.rois.forEach((roi) => {
|
77
|
-
// check multiplicity
|
78
|
-
if (roi.multiplicity) {
|
79
|
-
switch (roi.multiplicity.operator) {
|
80
|
-
case OperatorEnum.Eq:
|
81
|
-
if ((metadata.rois || []).filter((m) => m.role === roi.role).length !== roi.multiplicity.threshold) {
|
82
|
-
errors.push(formatString(strings.shapesOfRoleShouldBeEqualToThreshold, {
|
83
|
-
role: String(roi.role),
|
84
|
-
threshold: roi.multiplicity.threshold,
|
85
|
-
}));
|
86
|
-
}
|
87
|
-
break;
|
88
|
-
case OperatorEnum.Lt:
|
89
|
-
if ((metadata.rois || []).filter((m) => m.role === roi.role).length >= roi.multiplicity.threshold) {
|
90
|
-
errors.push(formatString(strings.shapesOfRoleShouldBeLessThanThreshold, {
|
91
|
-
role: String(roi.role),
|
92
|
-
threshold: roi.multiplicity.threshold,
|
93
|
-
}));
|
94
|
-
}
|
95
|
-
break;
|
96
|
-
case OperatorEnum.Lte:
|
97
|
-
if ((metadata.rois || []).filter((m) => m.role === roi.role).length > roi.multiplicity.threshold) {
|
98
|
-
errors.push(formatString(strings.shapesOfRoleShouldBeLessThanOrEqualToThreshold, {
|
99
|
-
role: String(roi.role),
|
100
|
-
threshold: roi.multiplicity.threshold,
|
101
|
-
}));
|
102
|
-
}
|
103
|
-
break;
|
104
|
-
case OperatorEnum.Gt:
|
105
|
-
if ((metadata.rois || []).filter((m) => m.role === roi.role).length <= roi.multiplicity.threshold) {
|
106
|
-
errors.push(formatString(strings.shapesOfRoleShouldBeGreaterThanThreshold, {
|
107
|
-
role: String(roi.role),
|
108
|
-
threshold: roi.multiplicity.threshold,
|
109
|
-
}));
|
110
|
-
}
|
111
|
-
break;
|
112
|
-
case OperatorEnum.Gte:
|
113
|
-
if ((metadata.rois || []).filter((m) => m.role === roi.role).length < roi.multiplicity.threshold) {
|
114
|
-
errors.push(formatString(strings.shapesOfRoleShouldBeGreaterThanOrEqualToThreshold, {
|
115
|
-
role: String(roi.role),
|
116
|
-
threshold: roi.multiplicity.threshold,
|
117
|
-
}));
|
118
|
-
}
|
119
|
-
}
|
120
|
-
}
|
121
|
-
});
|
122
|
-
// check rois metadata
|
123
|
-
Object.keys(shapes).forEach((shapeId) => {
|
124
|
-
var _a, _b;
|
125
|
-
const type = shapes[shapeId].type;
|
126
|
-
const confParameters = (_b = (_a = configuration.rois.find((r) => r.type === type)) === null || _a === void 0 ? void 0 : _a.parameters) !== null && _b !== void 0 ? _b : [];
|
127
|
-
confParameters.forEach((p) => {
|
128
|
-
var _a, _b;
|
129
|
-
if (p.required &&
|
130
|
-
isEmpty((_b = (_a = metadata.rois.find((r) => r.id === shapeId)) === null || _a === void 0 ? void 0 : _a.parameters.find((p) => p.codename === p.codename)) === null || _b === void 0 ? void 0 : _b.value)) {
|
131
|
-
errors.push(strings.missingRequiredValuesInShapeParameters.replace('{id}', shapeId));
|
132
|
-
}
|
133
|
-
});
|
134
|
-
});
|
135
|
-
return [errors.length === 0, errors];
|
136
|
-
};
|
137
|
-
export const fabricShapeToOutputShape = (shape, type, imageSize) => {
|
138
|
-
switch (type) {
|
139
|
-
case "rect" /* ToolEnum.Rectangle */:
|
140
|
-
return {
|
141
|
-
top: abs2Perc(shape.top, imageSize.height),
|
142
|
-
left: abs2Perc(shape.left, imageSize.width),
|
143
|
-
width: abs2Perc(shape.width, imageSize.width),
|
144
|
-
height: abs2Perc(shape.height, imageSize.height),
|
145
|
-
color: shape.stroke,
|
146
|
-
};
|
147
|
-
case "polygon" /* ToolEnum.Polygon */:
|
148
|
-
case "polyline" /* ToolEnum.Polyline */:
|
149
|
-
return {
|
150
|
-
points: shape
|
151
|
-
.get('points')
|
152
|
-
.map(({ x, y }) => ({
|
153
|
-
x: abs2Perc(x, imageSize.width),
|
154
|
-
y: abs2Perc(y, imageSize.height),
|
155
|
-
})),
|
156
|
-
top: abs2Perc(shape.top, imageSize.height),
|
157
|
-
left: abs2Perc(shape.left, imageSize.width),
|
158
|
-
color: shape.stroke,
|
159
|
-
};
|
160
|
-
}
|
161
|
-
};
|