import { types } from "mobx-state-tree";
|
|
import BaseTool, { DEFAULT_DIMENSIONS } from "./Base";
|
import ToolMixin from "../mixins/Tool";
|
import { ThreePointsDrawingTool, TwoPointsDrawingTool } from "../mixins/DrawingTool";
|
import { AnnotationMixin } from "../mixins/AnnotationMixin";
|
import { NodeViews } from "../components/Node/Node";
|
import { FF_DEV_3793, isFF } from "../utils/feature-flags";
|
|
const _BaseNPointTool = types
|
.model("BaseNTool", {
|
group: "segmentation",
|
smart: true,
|
shortcut: "tool:rect",
|
})
|
.views((self) => {
|
const Super = {
|
createRegionOptions: self.createRegionOptions,
|
isIncorrectControl: self.isIncorrectControl,
|
isIncorrectLabel: self.isIncorrectLabel,
|
};
|
|
return {
|
get getActivePolygon() {
|
const poly = self.currentArea;
|
|
if (poly && poly.closed) return null;
|
if (poly === undefined) return null;
|
if (poly && poly.type !== "rectangleregion") return null;
|
|
return poly;
|
},
|
|
get tagTypes() {
|
return {
|
stateTypes: "rectanglelabels",
|
controlTagTypes: ["rectanglelabels", "rectangle"],
|
};
|
},
|
get defaultDimensions() {
|
return DEFAULT_DIMENSIONS.rect;
|
},
|
createRegionOptions({ x, y }) {
|
return Super.createRegionOptions({
|
x,
|
y,
|
height: isFF(FF_DEV_3793) ? self.obj.canvasToInternalY(1) : 1,
|
width: isFF(FF_DEV_3793) ? self.obj.canvasToInternalX(1) : 1,
|
});
|
},
|
|
isIncorrectControl() {
|
return Super.isIncorrectControl() && self.current() === null;
|
},
|
isIncorrectLabel() {
|
return !self.current() && Super.isIncorrectLabel();
|
},
|
canStart() {
|
return self.current() === null && !self.annotation.isReadOnly();
|
},
|
|
current() {
|
return self.getActivePolygon;
|
},
|
};
|
})
|
.actions((self) => {
|
const Super = {
|
commitDrawingRegion: self.commitDrawingRegion,
|
};
|
|
return {
|
beforeCommitDrawing() {
|
const s = self.getActiveShape;
|
|
return s.width > self.MIN_SIZE.X && s.height > self.MIN_SIZE.Y;
|
},
|
|
commitDrawingRegion() {
|
const { currentArea, control, obj } = self;
|
|
if (!currentArea) return;
|
|
// Apply snap to pixel if enabled before finalizing the region
|
if (control?.snap === "pixel") {
|
const canvasX = currentArea.parent.internalToCanvasX(currentArea.x);
|
const canvasY = currentArea.parent.internalToCanvasY(currentArea.y);
|
const canvasWidth = currentArea.parent.internalToCanvasX(currentArea.width);
|
const canvasHeight = currentArea.parent.internalToCanvasY(currentArea.height);
|
|
// Apply snap logic through setPosition which handles both corners
|
currentArea.setPosition(canvasX, canvasY, canvasWidth, canvasHeight, currentArea.rotation);
|
}
|
|
// Use the parent commitDrawingRegion to finalize the region
|
return Super.commitDrawingRegion();
|
},
|
};
|
});
|
|
const _Tool = types
|
.model("RectangleTool", {
|
shortcut: "tool:rect",
|
})
|
.views((self) => ({
|
get viewTooltip() {
|
return "Rectangle";
|
},
|
get iconComponent() {
|
return self.dynamic ? NodeViews.RectRegionModel.altIcon : NodeViews.RectRegionModel.icon;
|
},
|
}));
|
|
const _Tool3Point = types
|
.model("Rectangle3PointTool", {
|
shortcut: "tool:rect-3point",
|
})
|
.views((self) => ({
|
get viewTooltip() {
|
return "3 Point Rectangle";
|
},
|
get iconComponent() {
|
return self.dynamic ? NodeViews.Rect3PointRegionModel.altIcon : NodeViews.Rect3PointRegionModel.icon;
|
},
|
}));
|
|
const Rect = types.compose(
|
_Tool.name,
|
ToolMixin,
|
BaseTool,
|
TwoPointsDrawingTool,
|
_BaseNPointTool,
|
_Tool,
|
AnnotationMixin,
|
);
|
|
const Rect3Point = types.compose(
|
_Tool3Point.name,
|
ToolMixin,
|
BaseTool,
|
ThreePointsDrawingTool,
|
_BaseNPointTool,
|
_Tool3Point,
|
AnnotationMixin,
|
);
|
|
export { Rect, Rect3Point };
|