From 7844debd9862b15d2b36bf9ce1efb3274616a313 Mon Sep 17 00:00:00 2001 From: Mohammad Amoush Date: Wed, 24 Jul 2019 18:53:21 -0400 Subject: Context Menu and Some Preview --- .../views/presentationview/PresentationElement.tsx | 58 ++++++++++++++++++++-- 1 file changed, 54 insertions(+), 4 deletions(-) (limited to 'src/client/views/presentationview/PresentationElement.tsx') diff --git a/src/client/views/presentationview/PresentationElement.tsx b/src/client/views/presentationview/PresentationElement.tsx index 329630875..f354a14c2 100644 --- a/src/client/views/presentationview/PresentationElement.tsx +++ b/src/client/views/presentationview/PresentationElement.tsx @@ -1,11 +1,11 @@ import { observer } from "mobx-react"; import React = require("react"); import { Doc, DocListCast, DocListCastAsync } from "../../../new_fields/Doc"; -import { NumCast, BoolCast, StrCast, Cast } from "../../../new_fields/Types"; +import { NumCast, BoolCast, StrCast, Cast, FieldValue } from "../../../new_fields/Types"; import { Id } from "../../../new_fields/FieldSymbols"; import { observable, action, computed, runInAction } from "mobx"; import "./PresentationView.scss"; -import { Utils } from "../../../Utils"; +import { Utils, emptyFunction, returnFalse } from "../../../Utils"; import { library } from '@fortawesome/fontawesome-svg-core'; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faFile as fileSolid, faFileDownload, faLocationArrow, faArrowUp, faSearch } from '@fortawesome/free-solid-svg-icons'; @@ -16,6 +16,11 @@ import { DragManager, SetupDrag, dropActionType } from "../../util/DragManager"; import { SelectionManager } from "../../util/SelectionManager"; import { indexOf } from "typescript-collections/dist/lib/arrays"; import { map } from "bluebird"; +import { ContextMenu } from "../ContextMenu"; +import { DocumentContentsView } from "../nodes/DocumentContentsView"; +import { Transform } from "../../util/Transform"; +import { FieldView } from "../nodes/FieldView"; +import { DocumentView } from "../nodes/DocumentView"; library.add(faArrowUp); library.add(fileSolid); @@ -768,8 +773,51 @@ export default class PresentationElement extends React.Component) => { + e.preventDefault(); + e.stopPropagation(); + ContextMenu.Instance.addItem({ description: this.embedInline ? "Collapse Inline" : "Expand Inline", event: () => this.embedInline = !this.embedInline, icon: "expand" }); + ContextMenu.Instance.displayMenu(e.clientX, e.clientY); + } + renderEmbeddedInline = () => { + if (!this.embedInline) { + return (null); + } + + // return ; + return ( + 1} + PanelWidth={() => 400} + PanelHeight={() => 400} + focus={(doc: Doc, willZoom: boolean) => { }} + selectOnLoad={false} + parentActive={returnFalse} + whenActiveChanged={(isActive: boolean) => { }} + bringToFront={(doc: Doc) => { }} + addDocTab={(doc: Doc, dataDoc: Doc | undefined, where: string) => { }} + zoomToScale={(scale: number) => { }} + getScale={() => 3.1415} + /> + ); + } render() { let p = this.props; @@ -786,7 +834,7 @@ export default class PresentationElement extends React.Component p.document, this.move, dropAction, this.props.mainDocument[Id], true); return ( -
{ p.gotoDocument(p.index, NumCast(this.props.mainDocument.selectedDoc)); e.stopPropagation(); }}> @@ -811,7 +860,8 @@ export default class PresentationElement extends React.Component - +
+ {this.renderEmbeddedInline()}
); } -- cgit v1.2.3-70-g09d2 From 3d5884541db27dca38dac25b773a0eae7451a57f Mon Sep 17 00:00:00 2001 From: Mohammad Amoush Date: Wed, 24 Jul 2019 21:15:42 -0400 Subject: Ask Bob About sizing and scaling --- .../views/presentationview/PresentationElement.tsx | 44 ++++++++++++++++------ .../views/presentationview/PresentationView.scss | 1 + 2 files changed, 33 insertions(+), 12 deletions(-) (limited to 'src/client/views/presentationview/PresentationElement.tsx') diff --git a/src/client/views/presentationview/PresentationElement.tsx b/src/client/views/presentationview/PresentationElement.tsx index f354a14c2..2091974ee 100644 --- a/src/client/views/presentationview/PresentationElement.tsx +++ b/src/client/views/presentationview/PresentationElement.tsx @@ -5,7 +5,7 @@ import { NumCast, BoolCast, StrCast, Cast, FieldValue } from "../../../new_field import { Id } from "../../../new_fields/FieldSymbols"; import { observable, action, computed, runInAction } from "mobx"; import "./PresentationView.scss"; -import { Utils, emptyFunction, returnFalse } from "../../../Utils"; +import { Utils, emptyFunction, returnFalse, returnOne } from "../../../Utils"; import { library } from '@fortawesome/fontawesome-svg-core'; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faFile as fileSolid, faFileDownload, faLocationArrow, faArrowUp, faSearch } from '@fortawesome/free-solid-svg-icons'; @@ -799,22 +799,42 @@ export default class PresentationElement extends React.Component; return ( + // 1} + // PanelWidth={() => 400} + // PanelHeight={() => 400} + // focus={(doc: Doc, willZoom: boolean) => { }} + // selectOnLoad={false} + // parentActive={returnFalse} + // whenActiveChanged={(isActive: boolean) => { }} + // bringToFront={(doc: Doc) => { }} + // addDocTab={(doc: Doc, dataDoc: Doc | undefined, where: string) => { }} + // zoomToScale={(scale: number) => { }} + // getScale={() => 3.1415} + // /> 1} - PanelWidth={() => 400} - PanelHeight={() => 400} - focus={(doc: Doc, willZoom: boolean) => { }} + addDocTab={returnFalse} + renderDepth={1} + PanelWidth={returnXDimension} + PanelHeight={returnYDimension} + focus={emptyFunction} selectOnLoad={false} parentActive={returnFalse} - whenActiveChanged={(isActive: boolean) => { }} - bringToFront={(doc: Doc) => { }} - addDocTab={(doc: Doc, dataDoc: Doc | undefined, where: string) => { }} - zoomToScale={(scale: number) => { }} - getScale={() => 3.1415} + whenActiveChanged={returnFalse} + bringToFront={emptyFunction} + zoomToScale={emptyFunction} + getScale={returnOne} + ContainingCollectionView={undefined} + ContentScaling={scale} /> ); } diff --git a/src/client/views/presentationview/PresentationView.scss b/src/client/views/presentationview/PresentationView.scss index 392ec1fb7..b8b4f23c4 100644 --- a/src/client/views/presentationview/PresentationView.scss +++ b/src/client/views/presentationview/PresentationView.scss @@ -23,6 +23,7 @@ .jsx-parser { height: 300px; width: 400px; + margin-top: 20px; } } -- cgit v1.2.3-70-g09d2 From f55dd40423b85efcdfbae1dd037743de9f6f15c4 Mon Sep 17 00:00:00 2001 From: Mohammad Amoush Date: Thu, 25 Jul 2019 12:51:59 -0400 Subject: Some Preview Shown. Css left --- src/client/views/presentationview/PresentationElement.tsx | 15 ++++++++------- src/client/views/presentationview/PresentationView.scss | 4 +++- 2 files changed, 11 insertions(+), 8 deletions(-) (limited to 'src/client/views/presentationview/PresentationElement.tsx') diff --git a/src/client/views/presentationview/PresentationElement.tsx b/src/client/views/presentationview/PresentationElement.tsx index 2091974ee..859ab9862 100644 --- a/src/client/views/presentationview/PresentationElement.tsx +++ b/src/client/views/presentationview/PresentationElement.tsx @@ -21,6 +21,7 @@ import { DocumentContentsView } from "../nodes/DocumentContentsView"; import { Transform } from "../../util/Transform"; import { FieldView } from "../nodes/FieldView"; import { DocumentView } from "../nodes/DocumentView"; +import { DocumentType } from "../../documents/Documents"; library.add(faArrowUp); library.add(fileSolid); @@ -656,7 +657,7 @@ export default class PresentationElement extends React.Component { - this.props.document.libraryBrush = true; + // this.props.document.libraryBrush = true; if (e.buttons === 1 && SelectionManager.GetIsDragging()) { let selected = NumCast(this.props.mainDocument.selectedDoc, 0); @@ -673,7 +674,7 @@ export default class PresentationElement extends React.Component { - this.props.document.libraryBrush = false; + // this.props.document.libraryBrush = false; //to get currently selected presentation doc let selected = NumCast(this.props.mainDocument.selectedDoc, 0); @@ -797,7 +798,7 @@ export default class PresentationElement extends React.Component false, this.props.removeDocByRef, this.move, // StrCast(this.props.document.dropAction) as dropActionType, (doc: Doc, dataDoc: Doc | undefined, where: string) => { }, Transform.Identity, () => ({ translateX: 0, translateY: 0 }), () => false, () => 400, 7)} // ; - + let scale = () => 175 / NumCast(this.props.document.nativeWidth, 175); return ( // { }} // getScale={() => 3.1415} // /> + 175} + PanelHeight={() => 175} focus={emptyFunction} selectOnLoad={false} parentActive={returnFalse} @@ -861,8 +863,7 @@ export default class PresentationElement extends React.Component { p.gotoDocument(p.index, NumCast(this.props.mainDocument.selectedDoc)); e.stopPropagation(); }}> diff --git a/src/client/views/presentationview/PresentationView.scss b/src/client/views/presentationview/PresentationView.scss index b8b4f23c4..c2d064941 100644 --- a/src/client/views/presentationview/PresentationView.scss +++ b/src/client/views/presentationview/PresentationView.scss @@ -19,12 +19,14 @@ -ms-user-select: none; user-select: none; transition: all .1s; + max-height: 250px; .jsx-parser { height: 300px; - width: 400px; + //width: 400px; margin-top: 20px; } + } .presentationView-item-above { -- cgit v1.2.3-70-g09d2 From 24a73583847e6ab00c8b1a00859129665e6ac212 Mon Sep 17 00:00:00 2001 From: Mohammad Amoush Date: Thu, 25 Jul 2019 19:03:04 -0400 Subject: Css Acting weird, fixes needed --- .../views/presentationview/PresentationElement.tsx | 66 ++++++++++++++-------- .../views/presentationview/PresentationView.scss | 14 ++++- 2 files changed, 55 insertions(+), 25 deletions(-) (limited to 'src/client/views/presentationview/PresentationElement.tsx') diff --git a/src/client/views/presentationview/PresentationElement.tsx b/src/client/views/presentationview/PresentationElement.tsx index 859ab9862..ff68f47ba 100644 --- a/src/client/views/presentationview/PresentationElement.tsx +++ b/src/client/views/presentationview/PresentationElement.tsx @@ -798,6 +798,8 @@ export default class PresentationElement extends React.Component false, this.props.removeDocByRef, this.move, // StrCast(this.props.document.dropAction) as dropActionType, (doc: Doc, dataDoc: Doc | undefined, where: string) => { }, Transform.Identity, () => ({ translateX: 0, translateY: 0 }), () => false, () => 400, 7)} // ; + let propDocWidth = NumCast(this.props.document.nativeWidth); + let propDocHeight = NumCast(this.props.document.nativeHeight); let scale = () => 175 / NumCast(this.props.document.nativeWidth, 175); return ( // { }} // getScale={() => 3.1415} // /> - - 175} - PanelHeight={() => 175} - focus={emptyFunction} - selectOnLoad={false} - parentActive={returnFalse} - whenActiveChanged={returnFalse} - bringToFront={emptyFunction} - zoomToScale={emptyFunction} - getScale={returnOne} - ContainingCollectionView={undefined} - ContentScaling={scale} - /> +
+ 20} + PanelHeight={() => 20} + focus={emptyFunction} + selectOnLoad={false} + parentActive={returnFalse} + whenActiveChanged={returnFalse} + bringToFront={emptyFunction} + zoomToScale={emptyFunction} + getScale={returnOne} + ContainingCollectionView={undefined} + ContentScaling={scale} + /> +
+
); } @@ -863,7 +885,7 @@ export default class PresentationElement extends React.Component { p.gotoDocument(p.index, NumCast(this.props.mainDocument.selectedDoc)); e.stopPropagation(); }}> diff --git a/src/client/views/presentationview/PresentationView.scss b/src/client/views/presentationview/PresentationView.scss index c2d064941..93cf0b365 100644 --- a/src/client/views/presentationview/PresentationView.scss +++ b/src/client/views/presentationview/PresentationView.scss @@ -19,12 +19,20 @@ -ms-user-select: none; user-select: none; transition: all .1s; - max-height: 250px; + //max-height: 250px; .jsx-parser { - height: 300px; + // height: 300px; //width: 400px; - margin-top: 20px; + // margin-top: 20px; + // overflow-y: scroll; + } + + .documentView-node { + // height: auto !important; + // width: aut !important; + position: absolute; + z-index: 1; } } -- cgit v1.2.3-70-g09d2 From 4e73b2b844846ee39e743f69df6225fb4cbf4f2c Mon Sep 17 00:00:00 2001 From: Mohammad Amoush Date: Fri, 26 Jul 2019 17:24:27 -0400 Subject: Preview shown with right css --- src/client/views/presentationview/PresentationElement.tsx | 14 ++++++++++---- src/client/views/presentationview/PresentationView.tsx | 2 +- 2 files changed, 11 insertions(+), 5 deletions(-) (limited to 'src/client/views/presentationview/PresentationElement.tsx') diff --git a/src/client/views/presentationview/PresentationElement.tsx b/src/client/views/presentationview/PresentationElement.tsx index ff68f47ba..3297acee9 100644 --- a/src/client/views/presentationview/PresentationElement.tsx +++ b/src/client/views/presentationview/PresentationElement.tsx @@ -800,7 +800,12 @@ export default class PresentationElement extends React.Component; let propDocWidth = NumCast(this.props.document.nativeWidth); let propDocHeight = NumCast(this.props.document.nativeHeight); - let scale = () => 175 / NumCast(this.props.document.nativeWidth, 175); + let previewWidth = NumCast(this.props.document.schemaPreviewWidth); + let scale = () => { + let newScale = 175 / NumCast(this.props.document.nativeWidth, 175); + console.log("New Scale: ", newScale); + return newScale; + }; return ( // { }} // getScale={() => 3.1415} // /> +
20} - PanelHeight={() => 20} + PanelWidth={() => 350} + PanelHeight={() => 100} focus={emptyFunction} selectOnLoad={false} parentActive={returnFalse} diff --git a/src/client/views/presentationview/PresentationView.tsx b/src/client/views/presentationview/PresentationView.tsx index 95458b4ca..718af1bf2 100644 --- a/src/client/views/presentationview/PresentationView.tsx +++ b/src/client/views/presentationview/PresentationView.tsx @@ -811,7 +811,7 @@ export class PresentationView extends React.Component { let width = NumCast(this.curPresentation.width); return ( -
+
{this.renderSelectOrPresSelection()} -- cgit v1.2.3-70-g09d2 From c6da9a2800037a951ea5070b4a77663401c4d00e Mon Sep 17 00:00:00 2001 From: Mohammad Amoush Date: Fri, 26 Jul 2019 18:52:30 -0400 Subject: resizable pres view --- .../views/presentationview/PresentationElement.tsx | 22 ----- .../views/presentationview/PresentationView.scss | 2 +- .../views/presentationview/PresentationView.tsx | 109 +++++++++++++++------ 3 files changed, 80 insertions(+), 53 deletions(-) (limited to 'src/client/views/presentationview/PresentationElement.tsx') diff --git a/src/client/views/presentationview/PresentationElement.tsx b/src/client/views/presentationview/PresentationElement.tsx index 3297acee9..fdddf0e41 100644 --- a/src/client/views/presentationview/PresentationElement.tsx +++ b/src/client/views/presentationview/PresentationElement.tsx @@ -800,36 +800,14 @@ export default class PresentationElement extends React.Component; let propDocWidth = NumCast(this.props.document.nativeWidth); let propDocHeight = NumCast(this.props.document.nativeHeight); - let previewWidth = NumCast(this.props.document.schemaPreviewWidth); let scale = () => { let newScale = 175 / NumCast(this.props.document.nativeWidth, 175); console.log("New Scale: ", newScale); return newScale; }; return ( - // 1} - // PanelWidth={() => 400} - // PanelHeight={() => 400} - // focus={(doc: Doc, willZoom: boolean) => { }} - // selectOnLoad={false} - // parentActive={returnFalse} - // whenActiveChanged={(isActive: boolean) => { }} - // bringToFront={(doc: Doc) => { }} - // addDocTab={(doc: Doc, dataDoc: Doc | undefined, where: string) => { }} - // zoomToScale={(scale: number) => { }} - // getScale={() => 3.1415} - // /> -
{ //Variable that holds reference to title input, so that new presentations get titles assigned. @observable titleInputElement: HTMLInputElement | undefined; @observable PresTitleChangeOpen: boolean = false; + @observable PresViewWidth: number | undefined; //initilize class variables constructor(props: PresViewProps) { @@ -81,6 +82,7 @@ export class PresentationView extends React.Component { //The first lifecycle function that gets called to set up the current presentation. async componentWillMount() { + this.props.Documents.forEach(async (doc, index: number) => { //For each presentation received from mainContainer, a mapping is created. @@ -806,43 +808,90 @@ export class PresentationView extends React.Component { this.presElementsMappings.set(keyDoc, elem); } + //_downsize = 0; + onPointerDown = (e: React.PointerEvent) => { + //this._downsize = e.clientX; + document.removeEventListener("pointermove", this.onPointerMove); + document.removeEventListener("pointerup", this.onPointerUp); + document.addEventListener("pointermove", this.onPointerMove); + document.addEventListener("pointerup", this.onPointerUp); + e.stopPropagation(); + e.preventDefault(); + } + @action + onPointerMove = (e: PointerEvent) => { + + this.curPresentation.width = Math.max(window.innerWidth - e.clientX, 255); + } + @action + onPointerUp = (e: PointerEvent) => { + //this.isPointerDown = false; + // if (Math.abs(e.clientX - this._downsize) < 4) { + // if (this.flyoutWidth < 5) this.flyoutWidth = 250; + // else this.flyoutWidth = 0; + // } + document.removeEventListener("pointermove", this.onPointerMove); + document.removeEventListener("pointerup", this.onPointerUp); + } + + togglePresView = (e) => { + e.stopPropagation(); + e.preventDefault(); + let width = NumCast(this.curPresentation.width); + if (width === 0) { + this.curPresentation.width = 255; + } else { + this.curPresentation.width = 0; + } + } + render() { let width = NumCast(this.curPresentation.width); + this.PresViewWidth = width; + return ( -
-
- {this.renderSelectOrPresSelection()} - - - - +
+
+
+ {this.renderSelectOrPresSelection()} + + + + +
+
+ + {this.renderPlayPauseButton()} + +
+ + this.presElementsMappings.clear()} + />
-
- - {this.renderPlayPauseButton()} - +
+
- this.presElementsMappings.clear()} - />
); } -- cgit v1.2.3-70-g09d2 From 215b73fbcfe0d6f205668e1bb7c755228e858ac9 Mon Sep 17 00:00:00 2001 From: Mohammad Amoush Date: Mon, 29 Jul 2019 19:19:49 -0400 Subject: PresMode, CLoseable Pres, and some bug fixes --- src/client/views/MainView.tsx | 2 +- .../views/presentationview/PresentationElement.tsx | 24 ++++- .../views/presentationview/PresentationList.tsx | 2 +- .../presentationview/PresentationModeMenu.scss | 30 ++++++ .../presentationview/PresentationModeMenu.tsx | 92 ++++++++++++++++ .../views/presentationview/PresentationView.scss | 2 +- .../views/presentationview/PresentationView.tsx | 116 +++++++++++++++++---- 7 files changed, 238 insertions(+), 30 deletions(-) create mode 100644 src/client/views/presentationview/PresentationModeMenu.scss create mode 100644 src/client/views/presentationview/PresentationModeMenu.tsx (limited to 'src/client/views/presentationview/PresentationElement.tsx') diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 53be0278e..0dbb241e4 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -267,7 +267,7 @@ export class MainView extends React.Component { zoomToScale={emptyFunction} getScale={returnOne} />} - {castRes ? : null} + {castRes ? : null}
} ; diff --git a/src/client/views/presentationview/PresentationElement.tsx b/src/client/views/presentationview/PresentationElement.tsx index fdddf0e41..05a70f79a 100644 --- a/src/client/views/presentationview/PresentationElement.tsx +++ b/src/client/views/presentationview/PresentationElement.tsx @@ -8,7 +8,7 @@ import "./PresentationView.scss"; import { Utils, emptyFunction, returnFalse, returnOne } from "../../../Utils"; import { library } from '@fortawesome/fontawesome-svg-core'; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { faFile as fileSolid, faFileDownload, faLocationArrow, faArrowUp, faSearch } from '@fortawesome/free-solid-svg-icons'; +import { faFile as fileSolid, faFileDownload, faLocationArrow, faArrowUp, faSearch, faArrowRight } from '@fortawesome/free-solid-svg-icons'; import { faFile as fileRegular } from '@fortawesome/free-regular-svg-icons'; import { List } from "../../../new_fields/List"; import { listSpec } from "../../../new_fields/Schema"; @@ -28,6 +28,7 @@ library.add(fileSolid); library.add(faLocationArrow); library.add(fileRegular as any); library.add(faSearch); +library.add(faArrowRight); interface PresentationElementProps { mainDocument: Doc; @@ -54,6 +55,7 @@ export enum buttonIndex { FadeAfter = 3, HideAfter = 4, Group = 5, + OpenRight = 6 } @@ -76,7 +78,7 @@ export default class PresentationElement extends React.Component { + e.stopPropagation(); + if (this.selectedButtons[buttonIndex.OpenRight]) { + this.selectedButtons[buttonIndex.OpenRight] = false; + // action maybe + } else { + this.selectedButtons[buttonIndex.OpenRight] = true; + } + this.autoSaveButtonChange(buttonIndex.OpenRight); + } + /** * Creating a drop target for drag and drop when called. */ @@ -637,7 +651,7 @@ export default class PresentationElement extends React.Component { let castedList = Cast(this.props.presButtonBackUp.selectedButtonDocs, listSpec(Doc)); - let foundSelectedButtons: boolean[] = new Array(6); + let foundSelectedButtons: boolean[] = new Array(7); //if this is the first time this doc mounts, push a doc for it to store for (let doc of castedList!) { @@ -887,6 +901,8 @@ export default class PresentationElement extends React.Component + +
{this.renderEmbeddedInline()}
diff --git a/src/client/views/presentationview/PresentationList.tsx b/src/client/views/presentationview/PresentationList.tsx index 2d63d41b5..2a31137af 100644 --- a/src/client/views/presentationview/PresentationList.tsx +++ b/src/client/views/presentationview/PresentationList.tsx @@ -95,7 +95,7 @@ export default class PresentationViewList extends React.Component this.props.PresElementsMappings.set(doc, e); } }} - key={doc[Id]} + key={doc[Id] + index} mainDocument={this.props.mainDocument} document={doc} index={index} diff --git a/src/client/views/presentationview/PresentationModeMenu.scss b/src/client/views/presentationview/PresentationModeMenu.scss new file mode 100644 index 000000000..336f43d20 --- /dev/null +++ b/src/client/views/presentationview/PresentationModeMenu.scss @@ -0,0 +1,30 @@ +.presMenu-cont { + position: fixed; + z-index: 10000; + height: 35px; + background: #323232; + box-shadow: 3px 3px 3px rgba(0, 0, 0, 0.25); + border-radius: 0px 6px 6px 6px; + overflow: hidden; + display: flex; + + .presMenu-button { + background-color: transparent; + width: 35px; + height: 35px; + } + + .presMenu-button:hover { + background-color: #121212; + } + + .presMenu-dragger { + height: 100%; + transition: width .2s; + background-image: url("https://logodix.com/logo/1020374.png"); + background-size: 90% 100%; + background-repeat: no-repeat; + background-position: left center; + } + +} \ No newline at end of file diff --git a/src/client/views/presentationview/PresentationModeMenu.tsx b/src/client/views/presentationview/PresentationModeMenu.tsx new file mode 100644 index 000000000..b3edeb1e2 --- /dev/null +++ b/src/client/views/presentationview/PresentationModeMenu.tsx @@ -0,0 +1,92 @@ +import React = require("react"); +import { observable, action, runInAction } from "mobx"; +import "./PresentationModeMenu.scss"; +import { observer } from "mobx-react"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; + + +export interface PresModeMenuProps { + next: () => void; + back: () => void; + presStatus: boolean; + startOrResetPres: () => void; + closePresMode: () => void; +} + +@observer +export default class PresModeMenu extends React.Component { + + @observable private _top: number = 20; + @observable private _right: number = 0; + @observable private _opacity: number = 1; + @observable private _transition: string = "opacity 0.5s"; + @observable private _transitionDelay: string = ""; + //@observable private Pinned: boolean = false; + + + private _mainCont: React.RefObject = React.createRef(); + + @action + pointerEntered = (e: React.PointerEvent) => { + this._transition = "opacity 0.1s"; + this._transitionDelay = ""; + this._opacity = 1; + } + + @action + dragging = (e: PointerEvent) => { + this._right -= e.movementX; + this._top += e.movementY; + + e.stopPropagation(); + e.preventDefault(); + } + + dragEnd = (e: PointerEvent) => { + document.removeEventListener("pointermove", this.dragging); + document.removeEventListener("pointerup", this.dragEnd); + e.stopPropagation(); + e.preventDefault(); + } + + dragStart = (e: React.PointerEvent) => { + document.removeEventListener("pointermove", this.dragging); + document.addEventListener("pointermove", this.dragging); + document.removeEventListener("pointerup", this.dragEnd); + document.addEventListener("pointerup", this.dragEnd); + let clientRect = this._mainCont.current!.getBoundingClientRect(); + + // runInAction(() => this._left = (clientRect.width - e.nativeEvent.offsetX) + clientRect.left); + // runInAction(() => this._top = e.nativeEvent.offsetY); + + e.stopPropagation(); + e.preventDefault(); + } + + renderPlayPauseButton = () => { + if (this.props.presStatus) { + return ; + } else { + return ; + } + } + + render() { + return ( +
+ + {this.renderPlayPauseButton()} + + +
+
+ ); + } + + + + +} \ No newline at end of file diff --git a/src/client/views/presentationview/PresentationView.scss b/src/client/views/presentationview/PresentationView.scss index ee413f379..97cbd4a24 100644 --- a/src/client/views/presentationview/PresentationView.scss +++ b/src/client/views/presentationview/PresentationView.scss @@ -66,7 +66,7 @@ padding-bottom: 3px; font-size: 25px; display: inline-block; - width: calc(100% - 160px); + width: calc(100% - 200px); } .presentation-icon { diff --git a/src/client/views/presentationview/PresentationView.tsx b/src/client/views/presentationview/PresentationView.tsx index de6c8ff82..70d86624c 100644 --- a/src/client/views/presentationview/PresentationView.tsx +++ b/src/client/views/presentationview/PresentationView.tsx @@ -4,7 +4,7 @@ import { observable, action, runInAction, reaction, autorun } from "mobx"; import "./PresentationView.scss"; import { DocumentManager } from "../../util/DocumentManager"; import { Utils } from "../../../Utils"; -import { Doc, DocListCast, DocListCastAsync } from "../../../new_fields/Doc"; +import { Doc, DocListCast, DocListCastAsync, WidthSym } from "../../../new_fields/Doc"; import { listSpec } from "../../../new_fields/Schema"; import { Cast, NumCast, FieldValue, PromiseValue, StrCast, BoolCast } from "../../../new_fields/Types"; import { Id } from "../../../new_fields/FieldSymbols"; @@ -12,11 +12,12 @@ import { List } from "../../../new_fields/List"; import PresentationElement, { buttonIndex } from "./PresentationElement"; import { library } from '@fortawesome/fontawesome-svg-core'; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { faArrowRight, faArrowLeft, faPlay, faStop, faPlus, faTimes, faMinus, faEdit } from '@fortawesome/free-solid-svg-icons'; +import { faArrowRight, faArrowLeft, faPlay, faStop, faPlus, faTimes, faMinus, faEdit, faEye } from '@fortawesome/free-solid-svg-icons'; import { Docs } from "../../documents/Documents"; import { undoBatch, UndoManager } from "../../util/UndoManager"; import PresentationViewList from "./PresentationList"; import { ContextMenu } from "../ContextMenu"; +import PresModeMenu from "./PresentationModeMenu"; library.add(faArrowLeft); library.add(faArrowRight); @@ -26,10 +27,12 @@ library.add(faPlus); library.add(faTimes); library.add(faMinus); library.add(faEdit); +library.add(faEye); export interface PresViewProps { Documents: List; + addDocTab: (doc: Doc) => void; } const expandedWidth = 400; @@ -63,7 +66,8 @@ export class PresentationView extends React.Component { //Variable that holds reference to title input, so that new presentations get titles assigned. @observable titleInputElement: HTMLInputElement | undefined; @observable PresTitleChangeOpen: boolean = false; - @observable PresViewWidth: number | undefined; + @observable presMode: boolean = false; + //initilize class variables constructor(props: PresViewProps) { @@ -360,11 +364,21 @@ export class PresentationView extends React.Component { //checking if curDoc has navigation open let curDocButtons = this.presElementsMappings.get(curDoc)!.selected; if (curDocButtons[buttonIndex.Navigate]) { - DocumentManager.Instance.jumpToDocument(curDoc, false); + // if (curDocButtons[buttonIndex.OpenRight]) { + // DocumentManager.Instance.jumpToDocument(curDoc, false); + // } else { + // DocumentManager.Instance.jumpToDocument(curDoc, false, undefined, this.props.addDocTab); + // } + this.jumpToTabOrRight(curDocButtons, curDoc); } else if (curDocButtons[buttonIndex.Show]) { let curScale = DocumentManager.Instance.getScaleOfDocView(this.childrenDocs[fromDoc]); - //awaiting jump so that new scale can be found, since jumping is async - await DocumentManager.Instance.jumpToDocument(curDoc, true); + if (curDocButtons[buttonIndex.OpenRight]) { + //awaiting jump so that new scale can be found, since jumping is async + await DocumentManager.Instance.jumpToDocument(curDoc, true); + } else { + await DocumentManager.Instance.jumpToDocument(curDoc, false, undefined, this.props.addDocTab); + } + let newScale = DocumentManager.Instance.getScaleOfDocView(curDoc); curDoc.viewScale = newScale; @@ -377,9 +391,15 @@ export class PresentationView extends React.Component { return; } let curScale = DocumentManager.Instance.getScaleOfDocView(this.childrenDocs[fromDoc]); + let curDocButtons = this.presElementsMappings.get(docToJump)!.selected; - //awaiting jump so that new scale can be found, since jumping is async - await DocumentManager.Instance.jumpToDocument(docToJump, willZoom); + + if (curDocButtons[buttonIndex.OpenRight]) { + //awaiting jump so that new scale can be found, since jumping is async + await DocumentManager.Instance.jumpToDocument(docToJump, willZoom); + } else { + await DocumentManager.Instance.jumpToDocument(docToJump, willZoom, undefined, this.props.addDocTab); + } let newScale = DocumentManager.Instance.getScaleOfDocView(curDoc); curDoc.viewScale = newScale; //saving the scale that user was on @@ -389,6 +409,15 @@ export class PresentationView extends React.Component { } + jumpToTabOrRight = (curDocButtons: boolean[], curDoc: Doc) => { + if (curDocButtons[buttonIndex.OpenRight]) { + DocumentManager.Instance.jumpToDocument(curDoc, false); + } else { + console.log("Open in tab!!"); + DocumentManager.Instance.jumpToDocument(curDoc, false, undefined, this.props.addDocTab); + } + } + /** * Async function that supposedly return the doc that is located at given index. */ @@ -578,18 +607,35 @@ export class PresentationView extends React.Component { //The function that starts or resets presentaton functionally, depending on status flag. @action - startOrResetPres = () => { + startOrResetPres = async () => { if (this.presStatus) { this.resetPresentation(); } else { this.presStatus = true; - this.startPresentation(0); + let startIndex = await this.findStartDocument(); + this.startPresentation(startIndex); const current = NumCast(this.curPresentation.selectedDoc); - this.gotoDocument(0, current); + this.gotoDocument(startIndex, current); } this.curPresentation.presStatus = this.presStatus; } + findStartDocument = async () => { + let docAtZero = await this.getDocAtIndex(0); + if (docAtZero === undefined) { + return 0; + } + let docAtZeroPresId = StrCast(docAtZero.presentId); + + if (this.groupMappings.has(docAtZeroPresId)) { + let group = this.groupMappings.get(docAtZeroPresId)!; + let lastDoc = group[group.length - 1]; + return this.childrenDocs.indexOf(lastDoc); + } else { + return 0; + } + } + //The function that resets the presentation by removing every action done by it. It also //stops the presentaton. @action @@ -808,9 +854,9 @@ export class PresentationView extends React.Component { this.presElementsMappings.set(keyDoc, elem); } - //_downsize = 0; + _downsize = 0; onPointerDown = (e: React.PointerEvent) => { - //this._downsize = e.clientX; + this._downsize = e.clientX; document.removeEventListener("pointermove", this.onPointerMove); document.removeEventListener("pointerup", this.onPointerUp); document.addEventListener("pointermove", this.onPointerMove); @@ -821,15 +867,16 @@ export class PresentationView extends React.Component { @action onPointerMove = (e: PointerEvent) => { - this.curPresentation.width = Math.max(window.innerWidth - e.clientX, 255); + this.curPresentation.width = Math.max(window.innerWidth - e.clientX, 300); } @action onPointerUp = (e: PointerEvent) => { - //this.isPointerDown = false; - // if (Math.abs(e.clientX - this._downsize) < 4) { - // if (this.flyoutWidth < 5) this.flyoutWidth = 250; - // else this.flyoutWidth = 0; - // } + if (Math.abs(e.clientX - this._downsize) < 4) { + let presWidth = NumCast(this.curPresentation.width); + if (presWidth - 300 !== 0) { + this.curPresentation.width = 0; + } + } document.removeEventListener("pointermove", this.onPointerMove); document.removeEventListener("pointerup", this.onPointerUp); } @@ -839,17 +886,38 @@ export class PresentationView extends React.Component { e.preventDefault(); let width = NumCast(this.curPresentation.width); if (width === 0) { - this.curPresentation.width = 255; - } else { + this.curPresentation.width = 300; + } + } + @action + openPresMode = () => { + if (!this.presMode) { this.curPresentation.width = 0; + this.presMode = true; + } + } + + @action + closePresMode = () => { + if (this.presMode) { + this.presMode = false; + this.curPresentation.width = 300; + } + + } + + renderPresMode = () => { + if (this.presMode) { + return ; + } else { + return (null); } + } render() { let width = NumCast(this.curPresentation.width); - this.PresViewWidth = width; - return (
@@ -857,6 +925,7 @@ export class PresentationView extends React.Component {
{this.renderSelectOrPresSelection()} +
+ {this.renderPresMode()}
); } -- cgit v1.2.3-70-g09d2 From 3468440a4297a105cf4138892c3d163ca9a0c83c Mon Sep 17 00:00:00 2001 From: Mohammad Amoush Date: Tue, 30 Jul 2019 11:30:48 -0400 Subject: CleanUp and Documentation --- .../views/presentationview/PresentationElement.tsx | 37 ++++++----- .../views/presentationview/PresentationList.tsx | 2 - .../presentationview/PresentationModeMenu.tsx | 34 ++++++---- .../views/presentationview/PresentationView.tsx | 76 ++++++++++++++-------- 4 files changed, 92 insertions(+), 57 deletions(-) (limited to 'src/client/views/presentationview/PresentationElement.tsx') diff --git a/src/client/views/presentationview/PresentationElement.tsx b/src/client/views/presentationview/PresentationElement.tsx index ccc3a72a9..11f3eb846 100644 --- a/src/client/views/presentationview/PresentationElement.tsx +++ b/src/client/views/presentationview/PresentationElement.tsx @@ -12,12 +12,8 @@ import { BoolCast, Cast, NumCast, StrCast } from "../../../new_fields/Types"; import { Utils, returnFalse, emptyFunction, returnOne } from "../../../Utils"; import { DragManager, dropActionType, SetupDrag } from "../../util/DragManager"; import { SelectionManager } from "../../util/SelectionManager"; -import { indexOf } from "typescript-collections/dist/lib/arrays"; -import { map } from "bluebird"; import { ContextMenu } from "../ContextMenu"; -import { DocumentContentsView } from "../nodes/DocumentContentsView"; import { Transform } from "../../util/Transform"; -import { FieldView } from "../nodes/FieldView"; import { DocumentView } from "../nodes/DocumentView"; import { DocumentType } from "../../documents/Documents"; import React = require("react"); @@ -73,9 +69,6 @@ export default class PresentationElement extends React.Component { //get the list that stores docs that keep track of buttons @@ -404,6 +400,10 @@ export default class PresentationElement extends React.Component { e.stopPropagation(); @@ -671,7 +671,6 @@ export default class PresentationElement extends React.Component { - // this.props.document.libraryBrush = true; if (e.buttons === 1 && SelectionManager.GetIsDragging()) { let selected = NumCast(this.props.mainDocument.selectedDoc, 0); @@ -688,7 +687,6 @@ export default class PresentationElement extends React.Component { - // this.props.document.libraryBrush = false; //to get currently selected presentation doc let selected = NumCast(this.props.mainDocument.selectedDoc, 0); @@ -787,15 +785,23 @@ export default class PresentationElement extends React.Component) => { e.preventDefault(); e.stopPropagation(); @@ -803,20 +809,19 @@ export default class PresentationElement extends React.Component { if (!this.embedInline) { return (null); } - // return
    - // {TreeView.GetChildElements([this.props.document], "", new Doc(), undefined, "", (doc: Doc, relativeTo?: Doc, before?: boolean) => false, this.props.removeDocByRef, this.move, - // StrCast(this.props.document.dropAction) as dropActionType, (doc: Doc, dataDoc: Doc | undefined, where: string) => { }, Transform.Identity, () => ({ translateX: 0, translateY: 0 }), () => false, () => 400, 7)} - //
; let propDocWidth = NumCast(this.props.document.nativeWidth); let propDocHeight = NumCast(this.props.document.nativeHeight); let scale = () => { let newScale = 175 / NumCast(this.props.document.nativeWidth, 175); - console.log("New Scale: ", newScale); return newScale; }; return ( @@ -836,7 +841,7 @@ export default class PresentationElement extends React.Component 350} - PanelHeight={() => 100} + PanelHeight={() => 90} focus={emptyFunction} selectOnLoad={false} parentActive={returnFalse} diff --git a/src/client/views/presentationview/PresentationList.tsx b/src/client/views/presentationview/PresentationList.tsx index 2d63d41b5..e853c4070 100644 --- a/src/client/views/presentationview/PresentationList.tsx +++ b/src/client/views/presentationview/PresentationList.tsx @@ -7,8 +7,6 @@ import { Doc, DocListCast, DocListCastAsync } from "../../../new_fields/Doc"; import { NumCast, StrCast } from "../../../new_fields/Types"; import { Id } from "../../../new_fields/FieldSymbols"; import PresentationElement, { buttonIndex } from "./PresentationElement"; -import { DragManager } from "../../util/DragManager"; -import { CollectionDockingView } from "../collections/CollectionDockingView"; import "../../../new_fields/Doc"; diff --git a/src/client/views/presentationview/PresentationModeMenu.tsx b/src/client/views/presentationview/PresentationModeMenu.tsx index b3edeb1e2..4de8da587 100644 --- a/src/client/views/presentationview/PresentationModeMenu.tsx +++ b/src/client/views/presentationview/PresentationModeMenu.tsx @@ -13,6 +13,10 @@ export interface PresModeMenuProps { closePresMode: () => void; } +/** + * This class is responsible for modeling of the Presentation Mode Menu. The menu allows + * user to navigate through presentation elements, and start/stop the presentation. + */ @observer export default class PresModeMenu extends React.Component { @@ -21,18 +25,14 @@ export default class PresModeMenu extends React.Component { @observable private _opacity: number = 1; @observable private _transition: string = "opacity 0.5s"; @observable private _transitionDelay: string = ""; - //@observable private Pinned: boolean = false; private _mainCont: React.RefObject = React.createRef(); - @action - pointerEntered = (e: React.PointerEvent) => { - this._transition = "opacity 0.1s"; - this._transitionDelay = ""; - this._opacity = 1; - } - + /** + * The function that changes the coordinates of the menu, depending on the + * movement of the mouse when it's being dragged. + */ @action dragging = (e: PointerEvent) => { this._right -= e.movementX; @@ -42,6 +42,10 @@ export default class PresModeMenu extends React.Component { e.preventDefault(); } + /** + * The function that removes the event listeners that are responsible for + * dragging of the menu. + */ dragEnd = (e: PointerEvent) => { document.removeEventListener("pointermove", this.dragging); document.removeEventListener("pointerup", this.dragEnd); @@ -49,20 +53,24 @@ export default class PresModeMenu extends React.Component { e.preventDefault(); } + /** + * The function that starts the dragging of the presentation mode menu. When + * the lines on further right are clicked on. + */ dragStart = (e: React.PointerEvent) => { document.removeEventListener("pointermove", this.dragging); document.addEventListener("pointermove", this.dragging); document.removeEventListener("pointerup", this.dragEnd); document.addEventListener("pointerup", this.dragEnd); - let clientRect = this._mainCont.current!.getBoundingClientRect(); - - // runInAction(() => this._left = (clientRect.width - e.nativeEvent.offsetX) + clientRect.left); - // runInAction(() => this._top = e.nativeEvent.offsetY); e.stopPropagation(); e.preventDefault(); } + /** + * The function that is responsible for rendering the play or pause button, depending on the + * status of the presentation. + */ renderPlayPauseButton = () => { if (this.props.presStatus) { return ; @@ -73,7 +81,7 @@ export default class PresModeMenu extends React.Component { render() { return ( -
{this.renderPlayPauseButton()} diff --git a/src/client/views/presentationview/PresentationView.tsx b/src/client/views/presentationview/PresentationView.tsx index ea85a8c6a..4fe9d3a1b 100644 --- a/src/client/views/presentationview/PresentationView.tsx +++ b/src/client/views/presentationview/PresentationView.tsx @@ -16,7 +16,6 @@ import { faArrowRight, faArrowLeft, faPlay, faStop, faPlus, faTimes, faMinus, fa import { Docs } from "../../documents/Documents"; import { undoBatch, UndoManager } from "../../util/UndoManager"; import PresentationViewList from "./PresentationList"; -import { ContextMenu } from "../ContextMenu"; import PresModeMenu from "./PresentationModeMenu"; import { CollectionDockingView } from "../collections/CollectionDockingView"; @@ -36,6 +35,7 @@ export interface PresViewProps { } const expandedWidth = 400; +const presMinWidth = 300; @observer export class PresentationView extends React.Component { @@ -408,6 +408,10 @@ export class PresentationView extends React.Component { } + /** + * This function checks if right option is clicked on a presentation element, if not it does open it as a tab + * with help of CollectionDockingView. + */ jumpToTabOrRight = (curDocButtons: boolean[], curDoc: Doc) => { if (curDocButtons[buttonIndex.OpenRight]) { DocumentManager.Instance.jumpToDocument(curDoc, false); @@ -460,22 +464,6 @@ export class PresentationView extends React.Component { } } - //removing it from the backUp of selected Buttons - // let castedList = Cast(this.presButtonBackUp.selectedButtonDocs, listSpec(Doc)); - // if (castedList) { - // castedList.forEach(async (doc, indexOfDoc) => { - // let curDoc = await doc; - // let curDocId = StrCast(curDoc.docId); - // if (curDocId === removedDoc[Id]) { - // if (castedList) { - // castedList.splice(indexOfDoc, 1); - // return; - // } - // } - // }); - - // } - //removing it from the backUp of selected Buttons let castedList = Cast(this.presButtonBackUp.selectedButtonDocs, listSpec(Doc)); if (castedList) { @@ -513,13 +501,16 @@ export class PresentationView extends React.Component { } } + /** + * An alternative remove method that removes a doc from presentation by its actual + * reference. + */ public removeDocByRef = (doc: Doc) => { let indexOfDoc = this.childrenDocs.indexOf(doc); const value = FieldValue(Cast(this.curPresentation.data, listSpec(Doc))); if (value) { value.splice(indexOfDoc, 1)[0]; } - //this.RemoveDoc(indexOfDoc, true); if (indexOfDoc !== - 1) { return true; } @@ -618,6 +609,11 @@ export class PresentationView extends React.Component { this.curPresentation.presStatus = this.presStatus; } + /** + * This method is called to find the start document of presentation. So + * that when user presses on play, the correct presentation element will be + * selected. + */ findStartDocument = async () => { let docAtZero = await this.getDocAtIndex(0); if (docAtZero === undefined) { @@ -848,10 +844,11 @@ export class PresentationView extends React.Component { this.curPresentation.title = newTitle; } - addPressElem = (keyDoc: Doc, elem: PresentationElement) => { - this.presElementsMappings.set(keyDoc, elem); - } - + /** + * On pointer down element that is catched on resizer of te + * presentation view. Sets up the event listeners to change the size with + * mouse move. + */ _downsize = 0; onPointerDown = (e: React.PointerEvent) => { this._downsize = e.clientX; @@ -862,16 +859,26 @@ export class PresentationView extends React.Component { e.stopPropagation(); e.preventDefault(); } + /** + * Changes the size of the presentation view, with mouse move. + * Minimum size is set to 300, so that every button is visible. + */ @action onPointerMove = (e: PointerEvent) => { - this.curPresentation.width = Math.max(window.innerWidth - e.clientX, 300); + this.curPresentation.width = Math.max(window.innerWidth - e.clientX, presMinWidth); } + + /** + * The method that is called on pointer up event. It checks if the button is just + * clicked so that presentation view will be closed. The way it's done is to check + * for minimal pixel change like 4, and accept it as it's just a click on top of the dragger. + */ @action onPointerUp = (e: PointerEvent) => { if (Math.abs(e.clientX - this._downsize) < 4) { let presWidth = NumCast(this.curPresentation.width); - if (presWidth - 300 !== 0) { + if (presWidth - presMinWidth !== 0) { this.curPresentation.width = 0; } } @@ -879,14 +886,23 @@ export class PresentationView extends React.Component { document.removeEventListener("pointerup", this.onPointerUp); } + /** + * This function gets triggered on click of the dragger. It opens up the + * presentation view, if it was closed beforehand. + */ togglePresView = (e: React.MouseEvent) => { e.stopPropagation(); e.preventDefault(); let width = NumCast(this.curPresentation.width); if (width === 0) { - this.curPresentation.width = 300; + this.curPresentation.width = presMinWidth; } } + /** + * This function is a setter that opens up the + * presentation mode, by setting it's render flag + * to true. It also closes the presentation view. + */ @action openPresMode = () => { if (!this.presMode) { @@ -895,15 +911,23 @@ export class PresentationView extends React.Component { } } + /** + * This function closes the presentation mode by setting its + * render flag to false. It also opens up the presentation view. + * By setting it to it's minimum size. + */ @action closePresMode = () => { if (this.presMode) { this.presMode = false; - this.curPresentation.width = 300; + this.curPresentation.width = presMinWidth; } } + /** + * Function that is called to render the presentation mode, depending on its flag. + */ renderPresMode = () => { if (this.presMode) { return ; -- cgit v1.2.3-70-g09d2 From 753615c80d4cf08605ebaaeeaf0a44a0fd88d898 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Sat, 3 Aug 2019 15:21:10 -0400 Subject: working version of clustering --- src/Utils.ts | 2 + src/client/documents/Documents.ts | 3 +- src/client/util/DragManager.ts | 8 +- src/client/views/MainView.tsx | 4 +- src/client/views/TemplateMenu.tsx | 5 +- .../views/collections/CollectionDockingView.tsx | 3 +- .../views/collections/CollectionSchemaView.tsx | 3 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 142 +++++++++++++-------- .../collections/collectionFreeForm/MarqueeView.tsx | 1 + .../views/nodes/CollectionFreeFormDocumentView.tsx | 12 +- src/client/views/nodes/DocumentView.tsx | 17 +-- .../views/presentationview/PresentationElement.tsx | 3 +- src/client/views/search/SearchItem.tsx | 3 +- 13 files changed, 125 insertions(+), 81 deletions(-) (limited to 'src/client/views/presentationview/PresentationElement.tsx') diff --git a/src/Utils.ts b/src/Utils.ts index 8df67df5d..502540eb0 100644 --- a/src/Utils.ts +++ b/src/Utils.ts @@ -140,6 +140,8 @@ export function returnOne() { return 1; } export function returnZero() { return 0; } +export function returnEmptyString() { return ""; } + export function emptyFunction() { } export type Without = Pick>; diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 09bafcf43..07e38a4c0 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -84,6 +84,7 @@ export interface DocumentOptions { templates?: List; viewType?: number; backgroundColor?: string; + defaultBackgroundColor?: string; dropAction?: dropActionType; backgroundLayout?: string; chromeStatus?: string; @@ -124,7 +125,7 @@ export namespace Docs { const TemplateMap: TemplateMap = new Map([ [DocumentType.TEXT, { layout: { view: FormattedTextBox }, - options: { height: 150, backgroundColor: "#f1efeb" } + options: { height: 150, backgroundColor: "#f1efeb", defaultBackgroundColor: "#f1efeb" } }], [DocumentType.HIST, { layout: { view: HistogramBox, collectionView: [CollectionView, data] as CollectionViewType }, diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 0b5c785a4..a7aaaed7c 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -404,7 +404,8 @@ export namespace DragManager { hideSource = options.hideSource(); } } - eles.map(ele => (ele.hidden = hideSource)); + eles.map(ele => (ele.hidden = hideSource) && + (ele.parentElement && ele.parentElement.className.indexOf("collectionFreeFormDocumentView") !== -1 && (ele.parentElement.hidden = hideSource))); let lastX = downX; let lastY = downY; @@ -434,7 +435,10 @@ export namespace DragManager { let hideDragElements = () => { dragElements.map(dragElement => dragElement.parentNode === dragDiv && dragDiv.removeChild(dragElement)); - eles.map(ele => (ele.hidden = false)); + eles.map(ele => { + ele.hidden = false; + (ele.parentElement && ele.parentElement.className.indexOf("collectionFreeFormDocumentView") !== -1 && (ele.parentElement.hidden = false)); + }); }; let endDrag = () => { document.removeEventListener("pointermove", moveHandler, true); diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 2ecf5fd85..53f589684 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -15,7 +15,7 @@ import { listSpec } from '../../new_fields/Schema'; import { Cast, FieldValue, NumCast, BoolCast, StrCast } from '../../new_fields/Types'; import { CurrentUserUtils } from '../../server/authentication/models/current_user_utils'; import { RouteStore } from '../../server/RouteStore'; -import { emptyFunction, returnOne, returnTrue, Utils } from '../../Utils'; +import { emptyFunction, returnOne, returnTrue, Utils, returnEmptyString } from '../../Utils'; import { DocServer } from '../DocServer'; import { Docs } from '../documents/Documents'; import { SetupDrag } from '../util/DragManager'; @@ -270,6 +270,7 @@ export class MainView extends React.Component { PanelWidth={this.getPWidth} PanelHeight={this.getPHeight} renderDepth={0} + backgroundColor={returnEmptyString} selectOnLoad={false} focus={emptyFunction} parentActive={returnTrue} @@ -334,6 +335,7 @@ export class MainView extends React.Component { renderDepth={0} selectOnLoad={false} focus={emptyFunction} + backgroundColor={returnEmptyString} parentActive={returnTrue} whenActiveChanged={emptyFunction} bringToFront={emptyFunction} diff --git a/src/client/views/TemplateMenu.tsx b/src/client/views/TemplateMenu.tsx index e654a0644..6dd908445 100644 --- a/src/client/views/TemplateMenu.tsx +++ b/src/client/views/TemplateMenu.tsx @@ -60,12 +60,9 @@ export class TemplateMenu extends React.Component { let de = new DragManager.DocumentDragData([topDoc], [undefined]); de.moveDocument = topDocView.props.moveDocument; let xf = newDocView.ContentDiv!.getBoundingClientRect(); - console.log("ex = " + ex + " " + xf.left + " " + (ex - xf.left)); DragManager.StartDocumentDrag([newDocView.ContentDiv!], de, ex, ey, { offsetX: (ex - xf.left), offsetY: (ey - xf.top), - handlers: { - dragComplete: () => { }, - }, + handlers: { dragComplete: () => { }, }, hideSource: false }); } diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index 588102f01..f559480ed 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -10,7 +10,7 @@ import { Id } from '../../../new_fields/FieldSymbols'; import { FieldId } from "../../../new_fields/RefField"; import { listSpec } from "../../../new_fields/Schema"; import { Cast, NumCast, StrCast, BoolCast } from "../../../new_fields/Types"; -import { emptyFunction, returnTrue, Utils, returnOne } from "../../../Utils"; +import { emptyFunction, returnTrue, Utils, returnOne, returnEmptyString } from "../../../Utils"; import { DocServer } from "../../DocServer"; import { DocumentManager } from '../../util/DocumentManager'; import { DragLinksAsDocuments, DragManager } from "../../util/DragManager"; @@ -607,6 +607,7 @@ export class DockedFrameRenderer extends React.Component { parentActive={returnTrue} whenActiveChanged={emptyFunction} focus={emptyFunction} + backgroundColor={returnEmptyString} addDocTab={this.addDocTab} ContainingCollectionView={undefined} zoomToScale={emptyFunction} diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index 9efd0d3ec..8218877ba 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -6,7 +6,7 @@ import { action, computed, observable, trace, untracked } from "mobx"; import { observer } from "mobx-react"; import ReactTable, { CellInfo, ComponentPropsGetterR, Column, RowInfo, ResizedChangeFunction, Resize } from "react-table"; import "react-table/react-table.css"; -import { emptyFunction, returnOne } from "../../../Utils"; +import { emptyFunction, returnOne, returnEmptyString } from "../../../Utils"; import { Doc, DocListCast, Field, Opt } from "../../../new_fields/Doc"; import { Id } from "../../../new_fields/FieldSymbols"; import { List } from "../../../new_fields/List"; @@ -999,6 +999,7 @@ export class CollectionSchemaPreview extends React.Component r1.left + r1.width || r2.left + r2.width < r1.left || r2.top > r1.top + r1.height || r2.top + r2.height < r1.top); } - _groupingBorder = 100; + _clusterDistance = 75; bounsdSelect(doc: Doc, doc2: Doc) { - var x2 = NumCast(doc2.x) - this._groupingBorder; - var y2 = NumCast(doc2.y) - this._groupingBorder; - var w2 = NumCast(doc2.width) + this._groupingBorder; - var h2 = NumCast(doc2.height) + this._groupingBorder; - var x = NumCast(doc.x) - this._groupingBorder; - var y = NumCast(doc.y) - this._groupingBorder; - var w = NumCast(doc.width) + this._groupingBorder; - var h = NumCast(doc.height) + this._groupingBorder; - if (this.intersectRect({ left: x, top: y, width: w, height: h }, { left: x2, top: y2, width: w2, height: h2 })) { + var x2 = NumCast(doc2.x) - this._clusterDistance; + var y2 = NumCast(doc2.y) - this._clusterDistance; + var w2 = NumCast(doc2.width) + this._clusterDistance; + var h2 = NumCast(doc2.height) + this._clusterDistance; + var x = NumCast(doc.x) - this._clusterDistance; + var y = NumCast(doc.y) - this._clusterDistance; + var w = NumCast(doc.width) + this._clusterDistance; + var h = NumCast(doc.height) + this._clusterDistance; + if (doc.z === doc2.z && this.intersectRect({ left: x, top: y, width: w, height: h }, { left: x2, top: y2, width: w2, height: h2 })) { return true; } return false; @@ -197,36 +199,83 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { return false; } + tryDragCluster(e: PointerEvent) { + let probe = this.getTransform().transformPoint(e.clientX, e.clientY); + let cluster = this.childDocs.reduce((cluster, cd) => { + let cx = NumCast(cd.x) - this._clusterDistance; + let cy = NumCast(cd.y) - this._clusterDistance; + let cw = NumCast(cd.width) + 2 * this._clusterDistance; + let ch = NumCast(cd.height) + 2 * this._clusterDistance; + if (!cd.z && this.intersectRect({ left: cx, top: cy, width: cw, height: ch }, { left: probe[0], top: probe[1], width: 1, height: 1 })) + return NumCast(cd.cluster); + return cluster; + }, -1); + if (cluster !== -1) { + let eles = this.childDocs.filter(cd => NumCast(cd.cluster) === cluster); + this.selectDocuments(eles); + let clusterDocs = SelectionManager.SelectedDocuments(); + SelectionManager.DeselectAll(); + let de = new DragManager.DocumentDragData(eles, eles.map(d => undefined)); + de.moveDocument = this.props.moveDocument; + const [left, top] = clusterDocs[0].props.ScreenToLocalTransform().scale(clusterDocs[0].props.ContentScaling()).inverse().transformPoint(0, 0); + const [xoff, yoff] = this.getTransform().transformDirection(e.x - left, e.y - top); + de.dropAction = e.ctrlKey || e.altKey ? "alias" : undefined; + de.xOffset = xoff; + de.yOffset = yoff; + DragManager.StartDocumentDrag(clusterDocs.map(v => v.ContentDiv!), de, e.clientX, e.clientY, { + handlers: { dragComplete: action(emptyFunction) }, + hideSource: !de.dropAction + }); + return true; + } + + return false; + } + @observable sets: (Doc[])[] = []; @action updateClusters() { - let sets: (Doc[])[] = [] + this.sets.length = 0; this.childDocs.map(c => { let included = [] - for (let i = 0; i < sets.length; i++) { - for (let j = 0; j < sets[i].length; j++) { - if (this.bounsdSelect(c, sets[i][j])) { + for (let i = 0; i < this.sets.length; i++) { + for (let j = 0; j < this.sets[i].length; j++) { + if (this.bounsdSelect(c, this.sets[i][j])) { included.push(i); break; } } } if (included.length === 0) - sets.push([c]); + this.sets.push([c]); else if (included.length === 1) - sets[included[0]].push(c); + this.sets[included[0]].push(c); else { - sets[included[0]].push(c); + this.sets[included[0]].push(c); for (let s = 1; s < included.length; s++) { - sets[included[0]].push(...sets[included[s]]); - sets[included[s]].length = 0; + this.sets[included[0]].push(...this.sets[included[s]]); + this.sets[included[s]].length = 0; } } }); - for (let s = 0; s < sets.length; s++) { - for (let i = 0; i < sets[s].length; i++) { - Doc.GetProto(sets[s][i]).cluster = s; + for (let s = 0; s < this.sets.length; s++) { + for (let i = 0; i < this.sets[s].length; i++) { + this.sets[s][i].cluster = s; + } + } + } + + getClusterColor = (doc: Doc) => { + if (this.props.Document.useClusters) { + let cluster = NumCast(doc.cluster); + let set = this.sets.length > cluster ? this.sets[NumCast(doc.cluster)] : undefined; + let colors = ["#da42429e", "#31ea318c", "#8c4000", "#4a7ae2c4", "#d809ff", "#ff7601", "#1dffff", "yellow", "#1b8231f2", "#000000ad"]; + let clusterColor = colors[cluster % colors.length]; + for (let i = 0; set && i < set.length; i++) { + if (set[i].backgroundColor && set[i].backgroundColor !== set[i].defaultBackgroundColor) clusterColor = StrCast(set[i].backgroundColor); } + return clusterColor; } + return ""; } @action @@ -249,34 +298,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { @action onPointerMove = (e: PointerEvent): void => { if (!e.cancelBubble) { - let probe = this.getTransform().transformPoint(e.clientX, e.clientY); - let cluster = this.childDocs.reduce((cluster, cd) => { - let cx = NumCast(cd.x) - this._groupingBorder; - let cy = NumCast(cd.y) - this._groupingBorder; - let cw = NumCast(cd.width) + 2 * this._groupingBorder; - let ch = NumCast(cd.height) + 2 * this._groupingBorder; - if (this.intersectRect({ left: cx, top: cy, width: cw, height: ch }, { left: probe[0], top: probe[1], width: 1, height: 1 })) - return NumCast(cd.cluster); - return cluster; - }, -1); - if (cluster !== -1) { - let eles = this.childDocs.filter(cd => NumCast(cd.cluster) === cluster); - this.selectDocuments(eles); - let clusterDocs = SelectionManager.SelectedDocuments(); - SelectionManager.DeselectAll(); - let de = new DragManager.DocumentDragData(eles, eles.map(d => undefined)); - de.moveDocument = this.props.moveDocument; - const [left, top] = clusterDocs[0].props.ScreenToLocalTransform().scale(clusterDocs[0].props.ContentScaling()).inverse().transformPoint(0, 0); - const [xoff, yoff] = this.getTransform().transformDirection(e.x - left, e.y - top); - de.dropAction = e.ctrlKey || e.altKey ? "alias" : undefined; - de.xOffset = xoff; - de.yOffset = yoff; - DragManager.StartDocumentDrag(clusterDocs.map(v => v.ContentDiv!), de, e.clientX, e.clientY, { - handlers: { - dragComplete: action(emptyFunction) - }, - hideSource: !de.dropAction - }); + if (this.props.Document.useClusters && this.tryDragCluster(e)) { e.stopPropagation(); // doesn't actually stop propagation since all our listeners are listening to events on 'document' however it does mark the event as cancelBubble=true which we test for in the move event handlers e.preventDefault(); document.removeEventListener("pointermove", this.onPointerMove); @@ -493,6 +515,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { ContentScaling: returnOne, ContainingCollectionView: this.props.CollectionView, focus: this.focusDocument, + backgroundColor: this.getClusterColor, parentActive: this.props.active, whenActiveChanged: this.props.whenActiveChanged, bringToFront: this.bringToFront, @@ -516,6 +539,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { ContentScaling: returnOne, ContainingCollectionView: this.props.CollectionView, focus: this.focusDocument, + backgroundColor: returnEmptyString, parentActive: this.props.active, whenActiveChanged: this.props.whenActiveChanged, bringToFront: this.bringToFront, @@ -625,6 +649,15 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { event: async () => this.props.Document.fitToBox = !this.fitToBox, icon: !this.fitToBox ? "expand-arrows-alt" : "compress-arrows-alt" }); + layoutItems.push({ + description: `${this.props.Document.useClusters ? "Uncluster" : "Use Clusters"}`, + event: async () => { + Docs.Prototypes.get(DocumentType.TEXT).defaultBackgroundColor = "#f1efeb"; + Docs.Prototypes.get(DocumentType.COL).defaultBackgroundColor = "white"; + this.props.Document.useClusters = !this.props.Document.useClusters; + }, + icon: !this.props.Document.useClusters ? "expand-arrows-alt" : "compress-arrows-alt" + }); layoutItems.push({ description: "Arrange contents in grid", icon: "table", @@ -700,10 +733,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { ...this.views ] private overlayChildViews = () => { - console.log(this.overlayViews.length); - return [ - ...this.overlayViews - ]; + return [...this.overlayViews]; } public static AddCustomLayout(doc: Doc, dataKey: string): () => void { diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index b9ee588dd..ff96bd993 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -278,6 +278,7 @@ export class MarqueeView extends React.Component panX: 0, panY: 0, backgroundColor: this.props.container.isAnnotationOverlay ? undefined : "white", + defaultBackgroundColor: this.props.container.isAnnotationOverlay ? undefined : "white", width: bounds.width, height: bounds.height, title: e.key === "s" || e.key === "S" ? "-summary-" : "a nested collection", diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 3b6c443c2..ee596c841 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -8,6 +8,7 @@ import { DocumentView, DocumentViewProps, positionSchema } from "./DocumentView" import "./DocumentView.scss"; import React = require("react"); import { Doc } from "../../../new_fields/Doc"; +import { returnEmptyString } from "../../../Utils"; export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps { x?: number; @@ -69,6 +70,11 @@ export class CollectionFreeFormDocumentView extends DocComponent this.clusterColor; + render() { const hasPosition = this.props.x !== undefined || this.props.y !== undefined; return ( @@ -77,7 +83,10 @@ export class CollectionFreeFormDocumentView extends DocComponent void; collapseToPoint?: (scrpt: number[], expandedDocs: Doc[] | undefined) => void; zoomToScale: (scale: number) => void; + backgroundColor: (doc: Doc) => string; getScale: () => number; animateBetweenIcon?: (iconPos: number[], startTime: number, maximizing: boolean) => void; ChromeHeight?: () => number; @@ -675,12 +676,9 @@ export class DocumentView extends DocComponent(Docu // to determine the render JSX string, otherwise the layout field should directly contain a JSX layout string. return this.props.Document.layout instanceof Doc ? this.props.Document.layout : this.props.Document; } + render() { - if (this.Document.hidden) { - return null; - } - let self = this; - let backgroundColor = StrCast(this.layoutDoc.backgroundColor); + let backgroundColor = this.props.backgroundColor(this.props.Document) || StrCast(this.layoutDoc.backgroundColor); let foregroundColor = StrCast(this.layoutDoc.color); var nativeWidth = this.nativeWidth > 0 && !BoolCast(this.props.Document.ignoreAspect) ? `${this.nativeWidth}px` : "100%"; var nativeHeight = BoolCast(this.props.Document.ignoreAspect) ? this.props.PanelHeight() / this.props.ContentScaling() : this.nativeHeight > 0 ? `${this.nativeHeight}px` : "100%"; @@ -695,8 +693,6 @@ export class DocumentView extends DocComponent(Docu }); } let showTextTitle = showTitle && StrCast(this.layoutDoc.layout).startsWith("(Docu color: foregroundColor, outlineColor: "maroon", outlineStyle: "dashed", - boxShadow: this.layoutDoc.isBackground ? - `0px 0px 50px 50px ${groupCol}` : - `${groupCol} ${StrCast(this.props.Document.boxShadow, `0vw 0vw ${50 / this.props.ContentScaling()}px`)}`, outlineWidth: BoolCast(this.layoutDoc.libraryBrush) && !StrCast(Doc.GetProto(this.props.Document).borderRounding) ? `${this.props.ScreenToLocalTransform().Scale}px` : "0px", marginLeft: BoolCast(this.layoutDoc.libraryBrush) && StrCast(Doc.GetProto(this.props.Document).borderRounding) ? @@ -717,7 +710,7 @@ export class DocumentView extends DocComponent(Docu border: BoolCast(this.layoutDoc.libraryBrush) && StrCast(Doc.GetProto(this.props.Document).borderRounding) ? `dashed maroon ${this.props.ScreenToLocalTransform().Scale}px` : undefined, borderRadius: "inherit", - background: this.layoutDoc.isBackground ? groupCol : backgroundColor, + background: backgroundColor, width: nativeWidth, height: nativeHeight, transform: `scale(${this.props.ContentScaling()})`, diff --git a/src/client/views/presentationview/PresentationElement.tsx b/src/client/views/presentationview/PresentationElement.tsx index 11f3eb846..e2d8daea9 100644 --- a/src/client/views/presentationview/PresentationElement.tsx +++ b/src/client/views/presentationview/PresentationElement.tsx @@ -9,7 +9,7 @@ import { Id } from "../../../new_fields/FieldSymbols"; import { List } from "../../../new_fields/List"; import { listSpec } from "../../../new_fields/Schema"; import { BoolCast, Cast, NumCast, StrCast } from "../../../new_fields/Types"; -import { Utils, returnFalse, emptyFunction, returnOne } from "../../../Utils"; +import { Utils, returnFalse, emptyFunction, returnOne, returnEmptyString } from "../../../Utils"; import { DragManager, dropActionType, SetupDrag } from "../../util/DragManager"; import { SelectionManager } from "../../util/SelectionManager"; import { ContextMenu } from "../ContextMenu"; @@ -843,6 +843,7 @@ export default class PresentationElement extends React.Component 350} PanelHeight={() => 90} focus={emptyFunction} + backgroundColor={returnEmptyString} selectOnLoad={false} parentActive={returnFalse} whenActiveChanged={returnFalse} diff --git a/src/client/views/search/SearchItem.tsx b/src/client/views/search/SearchItem.tsx index 0390359b3..1b9bba5c6 100644 --- a/src/client/views/search/SearchItem.tsx +++ b/src/client/views/search/SearchItem.tsx @@ -7,7 +7,7 @@ import { observer } from "mobx-react"; import { Doc, DocListCast, HeightSym, WidthSym } from "../../../new_fields/Doc"; import { Id } from "../../../new_fields/FieldSymbols"; import { Cast, NumCast, StrCast } from "../../../new_fields/Types"; -import { emptyFunction, returnFalse, returnOne, Utils } from "../../../Utils"; +import { emptyFunction, returnFalse, returnOne, Utils, returnEmptyString } from "../../../Utils"; import { DocumentType } from "../../documents/Documents"; import { DocumentManager } from "../../util/DocumentManager"; import { SetupDrag, DragManager } from "../../util/DragManager"; @@ -223,6 +223,7 @@ export class SearchItem extends React.Component { PanelWidth={returnXDimension} PanelHeight={returnYDimension} focus={emptyFunction} + backgroundColor={returnEmptyString} selectOnLoad={false} parentActive={returnFalse} whenActiveChanged={returnFalse} -- cgit v1.2.3-70-g09d2 From ebddce0975fa7e224e022cc075eee71abeacbe1d Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Wed, 7 Aug 2019 23:27:21 -0400 Subject: changed pdfs to render regions as collections. changed libraryBrush implementation. --- src/client/views/SearchItem.tsx | 6 ++-- .../views/collections/CollectionDockingView.tsx | 2 +- .../views/collections/CollectionSchemaView.tsx | 2 +- .../views/collections/CollectionTreeView.tsx | 8 ++--- src/client/views/nodes/DocumentView.tsx | 37 ++++++++++----------- src/client/views/nodes/FormattedTextBox.tsx | 2 +- src/client/views/pdf/PDFViewer.tsx | 3 +- src/client/views/pdf/Page.tsx | 9 ++--- .../views/presentationview/PresentationElement.tsx | 4 +-- src/client/views/search/SearchItem.tsx | 38 +++++++--------------- src/new_fields/Doc.ts | 18 ++++++++++ src/new_fields/util.ts | 1 - src/scraping/buxton/scraper.py | 9 ++--- 13 files changed, 65 insertions(+), 74 deletions(-) (limited to 'src/client/views/presentationview/PresentationElement.tsx') diff --git a/src/client/views/SearchItem.tsx b/src/client/views/SearchItem.tsx index 13e4b88f7..fd4b2420d 100644 --- a/src/client/views/SearchItem.tsx +++ b/src/client/views/SearchItem.tsx @@ -37,12 +37,10 @@ export class SearchItem extends React.Component { return ; } onPointerEnter = (e: React.PointerEvent) => { - this.props.doc.libraryBrush = true; - Doc.SetOnPrototype(this.props.doc, "protoBrush", true); + Doc.BrushDoc(this.props.doc); } onPointerLeave = (e: React.PointerEvent) => { - this.props.doc.libraryBrush = false; - Doc.SetOnPrototype(this.props.doc, "protoBrush", false); + Doc.UnBrushDoc(this.props.doc); } collectionRef = React.createRef(); diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index f559480ed..3af92cbe3 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -405,7 +405,7 @@ export class CollectionDockingView extends React.Component, dragSpan); + }}>, dragSpan); ReactDOM.render( CollectionDockingView.Instance.AddTab(stack, doc, dataDoc)} />, upDiv); tab.reactComponents = [dragSpan, upDiv]; tab.element.append(dragSpan); diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index 75787c0a8..ebfa737be 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -50,7 +50,7 @@ const columnTypes: Map = new Map([ ["title", ColumnType.String], ["x", ColumnType.Number], ["y", ColumnType.Number], ["width", ColumnType.Number], ["height", ColumnType.Number], ["nativeWidth", ColumnType.Number], ["nativeHeight", ColumnType.Number], ["isPrototype", ColumnType.Boolean], - ["page", ColumnType.Number], ["curPage", ColumnType.Number], ["libraryBrush", ColumnType.Boolean], ["zIndex", ColumnType.Number] + ["page", ColumnType.Number], ["curPage", ColumnType.Number], ["zIndex", ColumnType.Number] ]); @observer diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 571967743..24bd24d11 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -127,19 +127,19 @@ class TreeView extends React.Component { onPointerDown = (e: React.PointerEvent) => e.stopPropagation(); onPointerEnter = (e: React.PointerEvent): void => { - this.props.active() && (this.props.document.libraryBrush = true); + this.props.active() && Doc.BrushDoc(this.dataDoc); if (e.buttons === 1 && SelectionManager.GetIsDragging()) { this._header!.current!.className = "treeViewItem-header"; document.addEventListener("pointermove", this.onDragMove, true); } } onPointerLeave = (e: React.PointerEvent): void => { - this.props.document.libraryBrush = false; + Doc.UnBrushDoc(this.dataDoc); this._header!.current!.className = "treeViewItem-header"; document.removeEventListener("pointermove", this.onDragMove, true); } onDragMove = (e: PointerEvent): void => { - this.props.document.libraryBrush = false; + Doc.UnBrushDoc(this.dataDoc); let x = this.props.ScreenToLocalTransform().transformPoint(e.clientX, e.clientY); let rect = this._header!.current!.getBoundingClientRect(); let bounds = this.props.ScreenToLocalTransform().transformPoint(rect.left, rect.top + rect.height / 2); @@ -359,7 +359,7 @@ class TreeView extends React.Component { return <>
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index a7b4f33db..e911dc47c 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -303,7 +303,7 @@ export class DocumentView extends DocComponent(Docu fullScreenAlias.showCaption = true; this.props.addDocTab(fullScreenAlias, this.dataDoc, "inTab"); SelectionManager.DeselectAll(); - this.props.Document.libraryBrush = false; + Doc.UnBrushDoc(this.props.Document); } else if (CurrentUserUtils.MainDocId !== this.props.Document[Id] && (Math.abs(e.clientX - this._downX) < Utils.DRAG_THRESHOLD && @@ -445,13 +445,11 @@ export class DocumentView extends DocComponent(Docu targetDoc.targetContext = de.data.targetContext; let annotations = await DocListCastAsync(annotationDoc.annotations); if (annotations) { - annotations.forEach(anno => { - anno.target = targetDoc; - }); + annotations.forEach(anno => anno.target = targetDoc); } - let pdfDoc = await Cast(annotationDoc.pdfDoc, Doc); - if (pdfDoc) { - DocUtils.MakeLink(annotationDoc, targetDoc, this.props.ContainingCollectionView!.props.Document, `Annotation from ${StrCast(pdfDoc.title)}`, "", StrCast(pdfDoc.title)); + let annotDoc = await Cast(annotationDoc.annotationOn, Doc); + if (annotDoc) { + DocUtils.MakeLink(annotationDoc, targetDoc, this.props.ContainingCollectionView!.props.Document, `Annotation from ${StrCast(annotDoc.title)}`, "", StrCast(annotDoc.title)); } } if (de.data instanceof DragManager.LinkDragData) { @@ -647,8 +645,8 @@ export class DocumentView extends DocComponent(Docu }); } - onPointerEnter = (e: React.PointerEvent): void => { this.props.Document.libraryBrush = true; }; - onPointerLeave = (e: React.PointerEvent): void => { this.props.Document.libraryBrush = false; }; + onPointerEnter = (e: React.PointerEvent): void => { Doc.BrushDoc(this.props.Document); }; + onPointerLeave = (e: React.PointerEvent): void => { Doc.UnBrushDoc(this.props.Document); }; isSelected = () => SelectionManager.IsSelected(this); @action select = (ctrlPressed: boolean) => { SelectionManager.SelectDoc(this, ctrlPressed); }; @@ -695,22 +693,23 @@ export class DocumentView extends DocComponent(Docu }); } let showTextTitle = showTitle && StrCast(this.layoutDoc.layout).startsWith(" { annoDoc.color = color; annoDoc.type = AnnotationTypes.Region; annoDocs.push(annoDoc); - annoDoc.isBackground = true; + annoDoc.isButton = true; anno.remove(); this.props.addDocument && this.props.addDocument(annoDoc, false); mainAnnoDoc = annoDoc; @@ -208,7 +208,6 @@ export class PDFViewer extends React.Component { mainAnnoDocProto.y = Math.max(minY, 0); mainAnnoDocProto.annotations = new List(annoDocs); } - mainAnnoDocProto.pdfDoc = this.props.Document; mainAnnoDocProto.title = "Annotation on " + StrCast(this.props.Document.title); mainAnnoDocProto.annotationOn = this.props.Document; if (sourceDoc && createLink) { diff --git a/src/client/views/pdf/Page.tsx b/src/client/views/pdf/Page.tsx index 4986f44d5..6bd98cbaa 100644 --- a/src/client/views/pdf/Page.tsx +++ b/src/client/views/pdf/Page.tsx @@ -112,8 +112,8 @@ export default class Page extends React.Component { if (!BoolCast(annotationDoc.linkedToDoc)) { let annotations = await DocListCastAsync(annotationDoc.annotations); annotations && annotations.forEach(anno => anno.target = targetDoc); - let pdfDoc = await Cast(annotationDoc.pdfDoc, Doc); - pdfDoc && DocUtils.MakeLink(annotationDoc, targetDoc, dragData.targetContext, `Annotation from ${StrCast(pdfDoc.title)}`, "", StrCast(pdfDoc.title)) + let parentDoc = await Cast(annotationDoc.annotationOn, Doc); + parentDoc && DocUtils.MakeLink(annotationDoc, targetDoc, dragData.targetContext, `Annotation from ${StrCast(parentDoc.title)}`, "", StrCast(parentDoc.title)) } } }, @@ -144,10 +144,7 @@ export default class Page extends React.Component { onPointerDown = (e: React.PointerEvent): void => { // if alt+left click, drag and annotate if (NumCast(this.props.Document.scale, 1) !== 1) return; - if (e.altKey && e.button === 0) { - e.stopPropagation(); - } - else if (e.button === 0) { + if (!e.altKey && e.button === 0) { PDFMenu.Instance.StartDrag = this.startDrag; PDFMenu.Instance.Highlight = this.highlight; PDFMenu.Instance.Snippet = this.createSnippet; diff --git a/src/client/views/presentationview/PresentationElement.tsx b/src/client/views/presentationview/PresentationElement.tsx index e2d8daea9..d98b66324 100644 --- a/src/client/views/presentationview/PresentationElement.tsx +++ b/src/client/views/presentationview/PresentationElement.tsx @@ -706,7 +706,7 @@ export default class PresentationElement extends React.Component { - this.props.document.libraryBrush = false; + Doc.UnBrushDoc(this.props.document); let x = this.ScreenToLocalListTransform(e.clientX, e.clientY); let rect = this.header!.getBoundingClientRect(); let bounds = this.ScreenToLocalListTransform(rect.left, rect.top + rect.height / 2); @@ -889,7 +889,7 @@ export default class PresentationElement extends React.Component { p.gotoDocument(p.index, NumCast(this.props.mainDocument.selectedDoc)); e.stopPropagation(); }}> diff --git a/src/client/views/search/SearchItem.tsx b/src/client/views/search/SearchItem.tsx index c4af30f5c..8201aa374 100644 --- a/src/client/views/search/SearchItem.tsx +++ b/src/client/views/search/SearchItem.tsx @@ -105,23 +105,11 @@ export interface LinkMenuProps { @observer export class LinkContextMenu extends React.Component { - highlightDoc = (doc: Doc) => { - return () => { - doc.libraryBrush = true; - }; - } + highlightDoc = (doc: Doc) => () => Doc.BrushDoc(doc); - unHighlightDoc = (doc: Doc) => { - return () => { - doc.libraryBrush = false; - }; - } + unHighlightDoc = (doc: Doc) => () => Doc.UnBrushDoc(doc); - getOnClick(col: Doc) { - return () => { - CollectionDockingView.Instance.AddRightSplit(col, undefined); - }; - } + getOnClick = (col: Doc) => () => CollectionDockingView.Instance.AddRightSplit(col, undefined); render() { return ( @@ -286,14 +274,12 @@ export class SearchItem extends React.Component { let doc1 = Cast(this.props.doc.anchor1, Doc, null); let doc2 = Cast(this.props.doc.anchor2, Doc, null); - doc1 && (doc1.libraryBrush = true); - doc2 && (doc2.libraryBrush = true); + Doc.BrushDoc(doc1); + Doc.BrushDoc(doc2); } } else { - let docViews: DocumentView[] = DocumentManager.Instance.getAllDocumentViews(this.props.doc); - docViews.forEach(element => { - element.props.Document.libraryBrush = true; - }); + DocumentManager.Instance.getAllDocumentViews(this.props.doc).forEach(element => + Doc.BrushDoc(element.props.Document)); } } @@ -303,14 +289,12 @@ export class SearchItem extends React.Component { let doc1 = Cast(this.props.doc.anchor1, Doc, null); let doc2 = Cast(this.props.doc.anchor2, Doc, null); - doc1 && (doc1.libraryBrush = false); - doc2 && (doc2.libraryBrush = false); + Doc.UnBrushDoc(doc1); + Doc.UnBrushDoc(doc2); } } else { - let docViews: DocumentView[] = DocumentManager.Instance.getAllDocumentViews(this.props.doc); - docViews.forEach(element => { - element.props.Document.libraryBrush = false; - }); + DocumentManager.Instance.getAllDocumentViews(this.props.doc). + forEach(element => Doc.UnBrushDoc(element.props.Document)); } } diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts index c01f4e8cf..b3d1dc109 100644 --- a/src/new_fields/Doc.ts +++ b/src/new_fields/Doc.ts @@ -542,4 +542,22 @@ export namespace Doc { } }); } + + export class DocBrush { + @observable BrushedDoc: Doc[] = []; + } + const manager = new DocBrush(); + export function IsBrushed(doc: Doc) { + return manager.BrushedDoc.some(d => Doc.AreProtosEqual(d, doc)); + } + export function IsBrushedDegree(doc: Doc) { + return manager.BrushedDoc.some(d => d === doc) ? 2 : Doc.IsBrushed(doc) ? 1 : 0; + } + export function BrushDoc(doc: Doc) { + if (manager.BrushedDoc.indexOf(doc) === -1) runInAction(() => manager.BrushedDoc.push(doc)); + } + export function UnBrushDoc(doc: Doc) { + let index = manager.BrushedDoc.indexOf(doc); + if (index !== -1) runInAction(() => manager.BrushedDoc.splice(index, 1)); + } } \ No newline at end of file diff --git a/src/new_fields/util.ts b/src/new_fields/util.ts index c6f693f7f..48ae9f216 100644 --- a/src/new_fields/util.ts +++ b/src/new_fields/util.ts @@ -6,7 +6,6 @@ import { RefField } from "./RefField"; import { ObjectField } from "./ObjectField"; import { action } from "mobx"; import { Parent, OnUpdate, Update, Id, SelfProxy, Self } from "./FieldSymbols"; -import { ComputedField } from "./ScriptField"; function _readOnlySetter(): never { throw new Error("Documents can't be modified in read-only mode"); diff --git a/src/scraping/buxton/scraper.py b/src/scraping/buxton/scraper.py index f0f45d8f9..29cb8a256 100644 --- a/src/scraping/buxton/scraper.py +++ b/src/scraping/buxton/scraper.py @@ -88,8 +88,7 @@ def write_schema(parse_results, display_fields, storage_key): "panX": 0, "panY": 0, "zoomBasis": 1, - "zIndex": 2, - "libraryBrush": False, + "zIndex": 2 "viewType": 2 }, "__type": "Doc" @@ -130,8 +129,7 @@ def write_text_doc(content): "x": 10, "y": 10, "width": 400, - "zIndex": 2, - "libraryBrush": False + "zIndex": 2 }, "__type": "Doc" } @@ -183,8 +181,7 @@ def write_image(folder, name): "x": 10, "y": 10, "width": min(800, native_width), - "zIndex": 2, - "libraryBrush": False + "zIndex": 2 }, "__type": "Doc" } -- cgit v1.2.3-70-g09d2