diff options
Diffstat (limited to 'src/client/views/MarqueeAnnotator.tsx')
-rw-r--r-- | src/client/views/MarqueeAnnotator.tsx | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/src/client/views/MarqueeAnnotator.tsx b/src/client/views/MarqueeAnnotator.tsx index c18ac6738..f06f3efe0 100644 --- a/src/client/views/MarqueeAnnotator.tsx +++ b/src/client/views/MarqueeAnnotator.tsx @@ -28,6 +28,7 @@ export interface MarqueeAnnotatorProps { marqueeContainer: HTMLDivElement; docView: () => DocumentView; savedAnnotations: () => ObservableMap<number, HTMLDivElement[]>; + savedTapes: () => ObservableMap<number, HTMLDivElement[]>; selectionText: () => string; annotationLayer: HTMLDivElement; addDocument: (doc: Doc) => boolean; @@ -74,6 +75,7 @@ export class MarqueeAnnotator extends ObservableReactComponent<MarqueeAnnotatorP backgroundColor: color, annotationOn: this.props.Document, title: 'Annotation on ' + this.props.Document.title, + a, }); marqueeAnno.x = NumCast(doc.freeform_panX_min) + (parseInt(anno.style.left || '0') - containerOffset[0]) / scale; marqueeAnno.y = NumCast(doc.freeform_panY_min) + (parseInt(anno.style.top || '0') - containerOffset[1]) / scale; @@ -127,6 +129,140 @@ export class MarqueeAnnotator extends ObservableReactComponent<MarqueeAnnotatorP savedAnnoMap.clear(); return textRegionAnno; }; + + // @undoBatch + // makeTapeDocument = (color: string, isLinkButton?: boolean, savedTapes?: ObservableMap<number, HTMLDivElement[]>): Opt<Doc> => { + // const savedTapeMap = savedTapes?.values() && Array.from(savedTapes?.values()).length ? savedTapes : this.props.savedTapes(); + // if (savedTapeMap.size === 0) return undefined; + // const tapes = Array.from(savedTapeMap.values())[0]; + // const doc = this.props.Document; + // const scale = (this.props.annotationLayerScaling?.() || 1) * NumCast(doc._freeform_scale, 1); + // if (tapes.length && (tapes[0] as any).marqueeing) { + // const anno = tapes[0]; + // const containerOffset = this.props.containerOffset?.() || [0, 0]; + // const tape = Docs.Create.FreeformDocument([], { + // onClick: isLinkButton ? FollowLinkScript() : undefined, + // backgroundColor: color, + // annotationOn: this.props.Document, + // title: 'Tape on ' + this.props.Document.title, + // }); + // tape.x = NumCast(doc.freeform_panX_min) + (parseInt(anno.style.left || '0') - containerOffset[0]) / scale; + // tape.y = NumCast(doc.freeform_panY_min) + (parseInt(anno.style.top || '0') - containerOffset[1]) / scale; + // tape._height = parseInt(anno.style.height || '0') / scale; + // tape._width = parseInt(anno.style.width || '0') / scale; + // anno.remove(); + // savedTapeMap.clear(); + // return tape; + // } + + // const textRegionAnno = Docs.Create.ConfigDocument({ + // annotationOn: this.props.Document, + // text: this.props.selectionText() as any, // text want an RTFfield, but strings are acceptable, too. + // text_html: this.props.selectionText() as any, + // backgroundColor: 'transparent', + // presentation_duration: 2100, + // presentation_transition: 500, + // presentation_zoomText: true, + // title: '>' + this.props.Document.title, + // }); + // const textRegionAnnoProto = textRegionAnno[DocData]; + // let minX = Number.MAX_VALUE; + // let maxX = -Number.MAX_VALUE; + // let minY = Number.MAX_VALUE; + // let maxY = -Number.MIN_VALUE; + // const annoRects: string[] = []; + // savedAnnoMap.forEach((value: HTMLDivElement[]) => + // value.forEach(anno => { + // const x = parseInt(anno.style.left ?? '0'); + // const y = parseInt(anno.style.top ?? '0'); + // const height = parseInt(anno.style.height ?? '0'); + // const width = parseInt(anno.style.width ?? '0'); + // annoRects.push(`${x}:${y}:${width}:${height}`); + // anno.remove(); + // minY = Math.min(NumCast(y), minY); + // minX = Math.min(NumCast(x), minX); + // maxY = Math.max(NumCast(y) + NumCast(height), maxY); + // maxX = Math.max(NumCast(x) + NumCast(width), maxX); + // }) + // ); + + // textRegionAnnoProto.y = Math.max(minY, 0); + // textRegionAnnoProto.x = Math.max(minX, 0); + // textRegionAnnoProto.height = Math.max(maxY, 0) - Math.max(minY, 0); + // textRegionAnnoProto.width = Math.max(maxX, 0) - Math.max(minX, 0); + // textRegionAnnoProto.backgroundColor = color; + // // mainAnnoDocProto.text = this._selectionText; + // textRegionAnnoProto.text_inlineAnnotations = new List<string>(annoRects); + // textRegionAnnoProto.opacity = 0; + // textRegionAnnoProto.layout_unrendered = true; + // savedAnnoMap.clear(); + // return textRegionAnno; + // }; + + @undoBatch + makeTapeDocument = (color: string, isLinkButton?: boolean, savedTapes?: ObservableMap<number, HTMLDivElement[]>): Opt<Doc> => { + // const savedAnnoMap = savedTapes?.values() && Array.from(savedTapes?.values()).length ? savedTapes : this.props.savedTapes(); + // if (savedAnnoMap.size === 0) return undefined; + // const savedAnnos = Array.from(savedAnnoMap.values())[0]; + const doc = this.props.Document; + const scale = (this.props.annotationLayerScaling?.() || 1) * NumCast(doc._freeform_scale, 1); + const marqueeAnno = Docs.Create.FreeformDocument([], { + onClick: isLinkButton ? FollowLinkScript() : undefined, + backgroundColor: color, + annotationOn: this.props.Document, + title: 'Annotation on ' + this.props.Document.title, + }); + marqueeAnno.x = NumCast(doc.freeform_panX_min) / scale; + marqueeAnno.y = NumCast(doc.freeform_panY_min) / scale; + marqueeAnno._height = parseInt('100') / scale; + marqueeAnno._width = parseInt('100') / scale; + return marqueeAnno; + // } + + // const textRegionAnno = Docs.Create.ConfigDocument({ + // annotationOn: this.props.Document, + // text: this.props.selectionText() as any, // text want an RTFfield, but strings are acceptable, too. + // text_html: this.props.selectionText() as any, + // backgroundColor: 'transparent', + // presentation_duration: 2100, + // presentation_transition: 500, + // presentation_zoomText: true, + // title: '>' + this.props.Document.title, + // }); + // const textRegionAnnoProto = textRegionAnno[DocData]; + // let minX = Number.MAX_VALUE; + // let maxX = -Number.MAX_VALUE; + // let minY = Number.MAX_VALUE; + // let maxY = -Number.MIN_VALUE; + // const annoRects: string[] = []; + // savedAnnoMap.forEach((value: HTMLDivElement[]) => + // value.forEach(anno => { + // const x = parseInt(anno.style.left ?? '0'); + // const y = parseInt(anno.style.top ?? '0'); + // const height = parseInt(anno.style.height ?? '0'); + // const width = parseInt(anno.style.width ?? '0'); + // annoRects.push(`${x}:${y}:${width}:${height}`); + // anno.remove(); + // minY = Math.min(NumCast(y), minY); + // minX = Math.min(NumCast(x), minX); + // maxY = Math.max(NumCast(y) + NumCast(height), maxY); + // maxX = Math.max(NumCast(x) + NumCast(width), maxX); + // }) + // ); + + // textRegionAnnoProto.y = Math.max(minY, 0); + // textRegionAnnoProto.x = Math.max(minX, 0); + // textRegionAnnoProto.height = Math.max(maxY, 0) - Math.max(minY, 0); + // textRegionAnnoProto.width = Math.max(maxX, 0) - Math.max(minX, 0); + // textRegionAnnoProto.backgroundColor = color; + // // mainAnnoDocProto.text = this._selectionText; + // textRegionAnnoProto.text_inlineAnnotations = new List<string>(annoRects); + // textRegionAnnoProto.opacity = 0; + // textRegionAnnoProto.layout_unrendered = true; + // savedAnnoMap.clear(); + // return textRegionAnno; + }; + @action highlight = (color: string, isLinkButton: boolean, savedAnnotations?: ObservableMap<number, HTMLDivElement[]>, addAsAnnotation?: boolean) => { // creates annotation documents for current highlights @@ -136,6 +272,15 @@ export class MarqueeAnnotator extends ObservableReactComponent<MarqueeAnnotatorP return annotationDoc as Doc; }; + @action + tape = (color: string, isLinkButton: boolean, savedTapes?: ObservableMap<number, HTMLDivElement[]>, addAsAnnotation?: boolean) => { + // creates annotation documents for current highlights + const effectiveAcl = GetEffectiveAcl(this.props.Document[DocData]); + const tape = [AclAugment, AclSelfEdit, AclEdit, AclAdmin].includes(effectiveAcl) && this.makeTapeDocument(color, isLinkButton, savedTapes); + addAsAnnotation && tape && this.props.addDocument(tape); + return tape as Doc; + }; + public static previewNewAnnotation = action((savedAnnotations: ObservableMap<number, HTMLDivElement[]>, annotationLayer: HTMLDivElement, div: HTMLDivElement, page: number) => { div.style.backgroundColor = '#ACCEF7'; div.style.opacity = '0.5'; @@ -182,6 +327,7 @@ export class MarqueeAnnotator extends ObservableReactComponent<MarqueeAnnotatorP AnchorMenu.Instance.OnClick = undoable(() => this.props.anchorMenuClick?.()?.(this.highlight(this.props.highlightDragSrcColor ?? 'rgba(173, 216, 230, 0.75)', true, undefined, true)), 'make sidebar annotation'); AnchorMenu.Instance.OnAudio = unimplementedFunction; AnchorMenu.Instance.Highlight = (color: string) => this.highlight(color, false, undefined, true); + AnchorMenu.Instance.Tape = (color: string) => this.tape(color, false, undefined, true); AnchorMenu.Instance.GetAnchor = (savedAnnotations?: ObservableMap<number, HTMLDivElement[]> /* , addAsAnnotation?: boolean */) => this.highlight('rgba(173, 216, 230, 0.75)', true, savedAnnotations, true); AnchorMenu.Instance.onMakeAnchor = () => AnchorMenu.Instance.GetAnchor(undefined, true); |