import { getRoot, types } from "mobx-state-tree";
|
import { FF_DEV_3391, isFF } from "../../utils/feature-flags";
|
import { BaseTag } from "../TagBase";
|
import { SNAP_TO_PIXEL_MODE } from "../../components/ImageView/Image";
|
|
const ControlBase = types
|
.model({
|
...(isFF(FF_DEV_3391)
|
? {
|
id: types.identifier,
|
name: types.string,
|
}
|
: {
|
name: types.identifier,
|
}),
|
smart: true,
|
smartonly: false,
|
isControlTag: true,
|
})
|
.volatile(() => ({
|
snapMode: SNAP_TO_PIXEL_MODE.EDGE,
|
}))
|
.views((self) => ({
|
// historically two "types" were used and we should keep that backward compatibility:
|
// 1. name of control tag for describing labeled region;
|
// 2. label type to attach corresponding value to this region.
|
// usually they are the same, but with some problems:
|
// a. for hypertextlabels label type should be "htmllabels";
|
// original type are overwritten by Tree#buildData with real tag name,
|
// so _type was introduced to contain desired result type;
|
// b. but for textarea they differ from each other: "textarea" and "text".
|
// so now there is simple way to distinguish and overwrite them via two methods:
|
get resultType() {
|
return self.type;
|
},
|
|
// and
|
get valueType() {
|
return self.type;
|
},
|
|
get toNameTag() {
|
return self.annotation.names.get(self.toname);
|
},
|
|
selectedValues() {
|
throw new Error("Control tag needs to implement selectedValues method in views");
|
},
|
|
get result() {
|
return self.annotation.results.find((r) => r.from_name === self);
|
},
|
|
getSnappedPoint(point) {
|
if (self.snap === "pixel") {
|
return self.toNameTag.snapPointToPixel(point, self.snapMode);
|
}
|
return point;
|
},
|
|
get smartEnabled() {
|
const smart = self.smart ?? false;
|
const autoAnnotation = getRoot(self)?.autoAnnotation ?? false;
|
|
// @todo: Not sure why smartonly ignores autoAnnotation; It was like this from the beginning
|
return (autoAnnotation && smart) || self.smartonly || false;
|
},
|
}));
|
|
export default types.compose(ControlBase, BaseTag);
|