import { action, computed, makeObservable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { Doc, DocListCast, Opt, StrListCast } from '../../../fields/Doc';
import { Highlight } from '../../../fields/DocSymbols';
import { List } from '../../../fields/List';
import { BoolCast, DocCast, NumCast, StrCast } from '../../../fields/Types';
import { LinkManager } from '../../util/LinkManager';
import { undoable } from '../../util/UndoManager';
import { ObservableReactComponent } from '../ObservableReactComponent';
import { DocumentView } from '../nodes/DocumentView';
import { FieldViewProps } from '../nodes/FieldView';
import { OpenWhere } from '../nodes/OpenWhere';
import { AnchorMenu } from './AnchorMenu';
import './Annotation.scss';
import { Property } from 'csstype';
interface IRegionAnnotationProps {
x: number;
y: number;
width: number;
height: number;
opacity: () => number;
background: () => string;
outline: () => string | undefined;
}
const RegionAnnotation = function (props: IRegionAnnotationProps) {
return (
);
};
interface IAnnotationProps extends FieldViewProps {
annoDoc: Doc;
containerDataDoc: Doc;
fieldKey: string;
pointerEvents?: () => Opt;
}
@observer
export class Annotation extends ObservableReactComponent {
constructor(props: IAnnotationProps) {
super(props);
makeObservable(this);
}
@computed get linkHighlighted() {
const found = LinkManager.Instance.getAllDirectLinks(this._props.annoDoc).find(link => {
const a1 = Doc.getOppositeAnchor(link, this._props.annoDoc);
return a1 && Doc.GetBrushStatus(DocCast(a1.annotationOn, a1)!);
});
return found;
}
deleteAnnotation = undoable(() => {
const docAnnotations = DocListCast(this._props.containerDataDoc[this._props.fieldKey]);
this._props.containerDataDoc[this._props.fieldKey] = new List(docAnnotations.filter(a => a !== this._props.annoDoc));
AnchorMenu.Instance.fadeOut(true);
this._props.select(false);
}, 'delete annotation');
pinToPres = undoable(() => this._props.pinToPres(this._props.annoDoc, {}), 'pin to pres');
makeTargetToggle = undoable(() => { this._props.annoDoc.followLinkToggle = !this._props.annoDoc.followLinkToggle }, "set link toggle"); // prettier-ignore
isTargetToggler = () => BoolCast(this._props.annoDoc.followLinkToggle);
showTargetTrail = undoable((anchor: Doc) => {
const trail = DocCast(anchor.presentationTrail);
if (trail) {
Doc.ActivePresentation = trail;
this._props.addDocTab(trail, OpenWhere.replaceRight);
}
}, 'show target trail');
@action
onContextMenu = (e: React.MouseEvent) => {
AnchorMenu.Instance.Status = 'annotation';
AnchorMenu.Instance.Delete = this.deleteAnnotation;
AnchorMenu.Instance.Pinned = false;
AnchorMenu.Instance.PinToPres = this.pinToPres;
AnchorMenu.Instance.MakeTargetToggle = this.makeTargetToggle;
AnchorMenu.Instance.IsTargetToggler = this.isTargetToggler;
AnchorMenu.Instance.ShowTargetTrail = () => this.showTargetTrail(this._props.annoDoc);
AnchorMenu.Instance.jumpTo(e.clientX, e.clientY, true);
e.stopPropagation();
e.preventDefault();
};
@action
onPointerDown = (e: React.PointerEvent) => {
if (e.button === 2 || e.ctrlKey) {
e.stopPropagation();
e.preventDefault();
} else if (e.button === 0) {
e.stopPropagation();
DocumentView.FollowLink(undefined, this._props.annoDoc, false);
}
};
brushed = () => this._props.annoDoc && Doc.GetBrushHighlightStatus(this._props.annoDoc);
opacity = () => (this.brushed() === Doc.DocBrushStatus.highlighted ? 0.5 : 1);
outline = () => (this.linkHighlighted ? 'solid 1px lightBlue' : undefined);
background = () => (this._props.annoDoc[Highlight] ? 'orange' : StrCast(this._props.annoDoc.backgroundColor));
render() {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const forceRenderHack = [this.background(), this.outline(), this.opacity()]; // forces a re-render when these change -- because RegionAnnotation doesn't do this internally..
return (
{StrListCast(this._props.annoDoc.text_inlineAnnotations)
.map(a => a.split?.(':'))
.filter(fields => fields)
.map(([x, y, width, height], i) => (
{
Doc.BrushDoc(this._props.annoDoc);
}}
onPointerLeave={() => {
Doc.UnBrushDoc(this._props.annoDoc);
}}>
))}
);
}
}