diff options
| author | bobzel <zzzman@gmail.com> | 2023-04-05 22:44:03 -0400 |
|---|---|---|
| committer | bobzel <zzzman@gmail.com> | 2023-04-05 22:44:03 -0400 |
| commit | 9b41da1af16b982ee8ac2fc09f2f8b5d67eac9fb (patch) | |
| tree | bc3f57cd5b31fd453d272c925f6d5b728ab63bae /src/client/views/nodes/ComparisonBox.tsx | |
| parent | 9dae453967183b294bf4f7444b948023a1d52d39 (diff) | |
| parent | 8f7e99641f84ad15f34ba9e4a60b664ac93d2e5d (diff) | |
Merge branch 'master' into data-visualization-view-naafi
Diffstat (limited to 'src/client/views/nodes/ComparisonBox.tsx')
| -rw-r--r-- | src/client/views/nodes/ComparisonBox.tsx | 163 |
1 files changed, 104 insertions, 59 deletions
diff --git a/src/client/views/nodes/ComparisonBox.tsx b/src/client/views/nodes/ComparisonBox.tsx index 5ea6d567a..ace388c57 100644 --- a/src/client/views/nodes/ComparisonBox.tsx +++ b/src/client/views/nodes/ComparisonBox.tsx @@ -1,27 +1,34 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, observable } from 'mobx'; -import { observer } from "mobx-react"; +import { observer } from 'mobx-react'; import { Doc, Opt } from '../../../fields/Doc'; import { Cast, NumCast, StrCast } from '../../../fields/Types'; -import { emptyFunction, OmitKeys, returnFalse, returnNone, setupMoveUpEvents } from '../../../Utils'; +import { emptyFunction, returnFalse, returnNone, returnZero, setupMoveUpEvents } from '../../../Utils'; +import { Docs } from '../../documents/Documents'; import { DragManager } from '../../util/DragManager'; import { SnappingManager } from '../../util/SnappingManager'; import { undoBatch } from '../../util/UndoManager'; import { ViewBoxAnnotatableComponent, ViewBoxAnnotatableProps } from '../DocComponent'; import { StyleProp } from '../StyleProvider'; -import "./ComparisonBox.scss"; +import './ComparisonBox.scss'; import { DocumentView, DocumentViewProps } from './DocumentView'; import { FieldView, FieldViewProps } from './FieldView'; -import React = require("react"); - +import { PinProps, PresBox } from './trails'; +import React = require('react'); @observer export class ComparisonBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps & FieldViewProps>() { - public static LayoutString(fieldKey: string) { return FieldView.LayoutString(ComparisonBox, fieldKey); } - protected _multiTouchDisposer?: import("../../util/InteractionUtils").InteractionUtils.MultiTouchEventDisposer | undefined; + public static LayoutString(fieldKey: string) { + return FieldView.LayoutString(ComparisonBox, fieldKey); + } + protected _multiTouchDisposer?: import('../../util/InteractionUtils').InteractionUtils.MultiTouchEventDisposer | undefined; private _disposers: (DragManager.DragDropDisposer | undefined)[] = [undefined, undefined]; - @observable _animating = ""; + @observable _animating = ''; + + componentDidMount() { + this.props.setContentView?.(this); + } protected createDropTarget = (ele: HTMLDivElement | null, fieldKey: string, disposerId: number) => { this._disposers[disposerId]?.(); @@ -29,7 +36,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl // create disposers identified by disposerId to remove drag & drop listeners this._disposers[disposerId] = DragManager.MakeDropTarget(ele, (e, dropEvent) => this.dropHandler(e, dropEvent, fieldKey), this.layoutDoc); } - } + }; @undoBatch private dropHandler = (event: Event, dropEvent: DragManager.DropEvent, fieldKey: string) => { @@ -40,88 +47,126 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl this.dataDoc[fieldKey] = droppedDocs[0]; } } - } + }; private registerSliding = (e: React.PointerEvent<HTMLDivElement>, targetWidth: number) => { - e.button !== 2 && setupMoveUpEvents(this, e, this.onPointerMove, emptyFunction, action(() => { - // on click, animate slider movement to the targetWidth - this._animating = "all 200ms"; - this.layoutDoc._clipWidth = targetWidth * 100 / this.props.PanelWidth(); - setTimeout(action(() => this._animating = ""), 200); - }), false); - } + e.button !== 2 && + setupMoveUpEvents( + this, + e, + this.onPointerMove, + emptyFunction, + action(() => { + // on click, animate slider movement to the targetWidth + this._animating = 'all 200ms'; + this.layoutDoc._clipWidth = (targetWidth * 100) / this.props.PanelWidth(); + setTimeout( + action(() => (this._animating = '')), + 200 + ); + }), + false + ); + }; @action private onPointerMove = ({ movementX }: PointerEvent) => { - const width = movementX * this.props.ScreenToLocalTransform().Scale + NumCast(this.layoutDoc._clipWidth) / 100 * this.props.PanelWidth(); + const width = movementX * this.props.ScreenToLocalTransform().Scale + (NumCast(this.layoutDoc._clipWidth) / 100) * this.props.PanelWidth(); if (width && width > 5 && width < this.props.PanelWidth()) { - this.layoutDoc._clipWidth = width * 100 / this.props.PanelWidth(); + this.layoutDoc._clipWidth = (width * 100) / this.props.PanelWidth(); } return false; - } + }; + + getAnchor = (addAsAnnotation: boolean, pinProps?: PinProps) => { + const anchor = Docs.Create.ImageanchorDocument({ title: 'ImgAnchor:' + this.rootDoc.title, presTransition: 1000, unrendered: true, annotationOn: this.rootDoc }); + if (anchor) { + if (!addAsAnnotation) anchor.backgroundColor = 'transparent'; + /* addAsAnnotation &&*/ this.addDocument(anchor); + PresBox.pinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), clippable: true } }, this.rootDoc); + return anchor; + } + return this.rootDoc; + }; @undoBatch clearDoc = (e: React.MouseEvent, fieldKey: string) => { e.stopPropagation; // prevent click event action (slider movement) in registerSliding delete this.dataDoc[fieldKey]; - } + }; docStyleProvider = (doc: Opt<Doc>, props: Opt<DocumentViewProps>, property: string): any => { - if (property === StyleProp.PointerEvents) return "none"; + if (property === StyleProp.PointerEvents) return 'none'; return this.props.styleProvider?.(doc, props, property); - } + }; render() { - const clipWidth = NumCast(this.layoutDoc._clipWidth) + "%"; + const clipWidth = NumCast(this.layoutDoc._clipWidth) + '%'; const clearButton = (which: string) => { - return <div className={`clear-button ${which}`} - onPointerDown={e => e.stopPropagation()} // prevent triggering slider movement in registerSliding - onClick={e => this.clearDoc(e, which)}> - <FontAwesomeIcon className={`clear-button ${which}`} icon={"times"} size="sm" /> - </div>; + return ( + <div + className={`clear-button ${which}`} + onPointerDown={e => e.stopPropagation()} // prevent triggering slider movement in registerSliding + onClick={e => this.clearDoc(e, which)}> + <FontAwesomeIcon className={`clear-button ${which}`} icon={'times'} size="sm" /> + </div> + ); }; const displayDoc = (which: string) => { const whichDoc = Cast(this.dataDoc[which], Doc, null); // if (whichDoc?.type === DocumentType.MARKER) whichDoc = Cast(whichDoc.annotationOn, Doc, null); const targetDoc = Cast(whichDoc?.annotationOn, Doc, null) ?? whichDoc; - return whichDoc ? <> - <DocumentView - ref={(r) => { - whichDoc !== targetDoc && r?.focus(whichDoc); - }} - {...OmitKeys(this.props, ["NativeWidth", "NativeHeight"]).omit} - isContentActive={returnFalse} - isDocumentActive={returnFalse} - styleProvider={this.docStyleProvider} - Document={targetDoc} - DataDoc={undefined} - hideLinkButton={true} - pointerEvents={returnNone} /> - {clearButton(which)} - </> : // placeholder image if doc is missing + return whichDoc ? ( + <> + <DocumentView + ref={r => { + //whichDoc !== targetDoc && r?.focus(whichDoc, { instant: true }); + }} + {...this.props} + NativeWidth={returnZero} + NativeHeight={returnZero} + isContentActive={returnFalse} + isDocumentActive={returnFalse} + styleProvider={this.docStyleProvider} + Document={targetDoc} + DataDoc={undefined} + hideLinkButton={true} + pointerEvents={returnNone} + /> + {clearButton(which)} + </> // placeholder image if doc is missing + ) : ( <div className="placeholder"> - <FontAwesomeIcon className="upload-icon" icon={"cloud-upload-alt"} size="lg" /> - </div>; + <FontAwesomeIcon className="upload-icon" icon={'cloud-upload-alt'} size="lg" /> + </div> + ); }; const displayBox = (which: string, index: number, cover: number) => { - return <div className={`${which}Box-cont`} key={which} style={{ width: this.props.PanelWidth() }} - onPointerDown={e => this.registerSliding(e, cover)} - ref={ele => this.createDropTarget(ele, which, index)} > - {displayDoc(which)} - </div>; + return ( + <div className={`${which}Box-cont`} key={which} style={{ width: this.props.PanelWidth() }} onPointerDown={e => this.registerSliding(e, cover)} ref={ele => this.createDropTarget(ele, which, index)}> + {displayDoc(which)} + </div> + ); }; return ( - <div className={`comparisonBox${this.props.isContentActive() || SnappingManager.GetIsDragging() ? "-interactive" : ""}` /* change className to easily disable/enable pointer events in CSS */}> - {displayBox(this.fieldKey === "data" ? "compareBox-after" : `${this.fieldKey}2`, 1, this.props.PanelWidth() - 3)} - <div className="clip-div" style={{ width: clipWidth, transition: this._animating, background: StrCast(this.layoutDoc._backgroundColor, "gray") }}> - {displayBox(this.fieldKey === "data" ? "compareBox-before" : `${this.fieldKey}1`, 0, 0)} + <div className={`comparisonBox${this.props.isContentActive() || SnappingManager.GetIsDragging() ? '-interactive' : ''}` /* change className to easily disable/enable pointer events in CSS */}> + {displayBox(this.fieldKey === 'data' ? 'compareBox-after' : `${this.fieldKey}2`, 1, this.props.PanelWidth() - 3)} + <div className="clip-div" style={{ width: clipWidth, transition: this._animating, background: StrCast(this.layoutDoc._backgroundColor, 'gray') }}> + {displayBox(this.fieldKey === 'data' ? 'compareBox-before' : `${this.fieldKey}1`, 0, 0)} </div> - <div className="slide-bar" style={{ left: `calc(${clipWidth} - 0.5px)`, cursor: NumCast(this.layoutDoc._clipWidth) < 5 ? "e-resize" : NumCast(this.layoutDoc._clipWidth) / 100 > (this.props.PanelWidth() - 5) / this.props.PanelWidth() ? "w-resize" : undefined }} - onPointerDown={e => this.registerSliding(e, this.props.PanelWidth() / 2)} /* if clicked, return slide-bar to center */ > + <div + className="slide-bar" + style={{ + left: `calc(${clipWidth} - 0.5px)`, + cursor: NumCast(this.layoutDoc._clipWidth) < 5 ? 'e-resize' : NumCast(this.layoutDoc._clipWidth) / 100 > (this.props.PanelWidth() - 5) / this.props.PanelWidth() ? 'w-resize' : undefined, + }} + onPointerDown={e => this.registerSliding(e, this.props.PanelWidth() / 2)} /* if clicked, return slide-bar to center */ + > <div className="slide-handle" /> </div> - </div >); + </div> + ); } -}
\ No newline at end of file +} |
