diff options
| author | andrewdkim <adkim414@gmail.com> | 2019-07-26 17:37:12 -0400 | 
|---|---|---|
| committer | andrewdkim <adkim414@gmail.com> | 2019-07-26 17:37:12 -0400 | 
| commit | 2dfd6378cf3f472132143bc231090777e49eeec7 (patch) | |
| tree | 34e631e0551391e5786ae136ba1d596dbc876c76 /src/client/views/nodes/DocumentView.tsx | |
| parent | 7cb850105aeefd1234f76aaab5badd45a8660dc4 (diff) | |
| parent | e189378e5ce01eedd1373172fbd8d8dabf2ad197 (diff) | |
Merge branch 'master' of https://github.com/browngraphicslab/Dash-Web into animationtimeline
Diffstat (limited to 'src/client/views/nodes/DocumentView.tsx')
| -rw-r--r-- | src/client/views/nodes/DocumentView.tsx | 90 | 
1 files changed, 54 insertions, 36 deletions
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 907ba3713..bae0b5b96 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -37,6 +37,7 @@ import { RouteStore } from '../../../server/RouteStore';  import { FormattedTextBox } from './FormattedTextBox';  import { OverlayView } from '../OverlayView';  import { ScriptingRepl } from '../ScriptingRepl'; +import { ClientUtils } from '../../util/ClientUtils';  import { EditableView } from '../EditableView';  const JsxParser = require('react-jsx-parser').default; //TODO Why does this need to be imported like this? @@ -59,6 +60,7 @@ library.add(fa.faCrosshairs);  library.add(fa.faDesktop);  library.add(fa.faUnlock);  library.add(fa.faLock); +library.add(fa.faLaptopCode);  // const linkSchema = createSchema({ @@ -193,10 +195,10 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu                  DocumentView.animateBetweenIconFunc(doc, width, height, stime, maximizing, cb);              }              else { -                Doc.GetProto(doc).isMinimized = !maximizing; -                Doc.GetProto(doc).isIconAnimating = undefined; +                doc.isMinimized = !maximizing; +                doc.isIconAnimating = undefined;              } -            Doc.GetProto(doc).willMaximize = false; +            doc.willMaximize = false;          },              2);      } @@ -295,9 +297,11 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu          if (this._doubleTap && this.props.renderDepth) {              let fullScreenAlias = Doc.MakeAlias(this.props.Document);              fullScreenAlias.templates = new List<string>(); +            Doc.UseDetailLayout(fullScreenAlias); +            fullScreenAlias.showCaption = true;              this.props.addDocTab(fullScreenAlias, this.dataDoc, "inTab");              SelectionManager.DeselectAll(); -            this.props.Document.libraryBrush = undefined; +            this.props.Document.libraryBrush = false;          }          else if (CurrentUserUtils.MainDocId !== this.props.Document[Id] &&              (Math.abs(e.clientX - this._downX) < Utils.DRAG_THRESHOLD && @@ -316,20 +320,19 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu                  expandedDocs = summarizedDocs ? [...summarizedDocs, ...expandedDocs] : expandedDocs;                  // let expandedDocs = [...(subBulletDocs ? subBulletDocs : []), ...(maximizedDocs ? maximizedDocs : []), ...(summarizedDocs ? summarizedDocs : []),];                  if (expandedDocs.length) {   // bcz: need a better way to associate behaviors with click events on widget-documents -                    let expandedProtoDocs = expandedDocs.map(doc => Doc.GetProto(doc));                      let maxLocation = StrCast(this.props.Document.maximizeLocation, "inPlace");                      let getDispDoc = (target: Doc) => Object.getOwnPropertyNames(target).indexOf("isPrototype") === -1 ? target : Doc.MakeDelegate(target);                      if (altKey || ctrlKey) {                          maxLocation = this.props.Document.maximizeLocation = (ctrlKey ? maxLocation : (maxLocation === "inPlace" || !maxLocation ? "inTab" : "inPlace"));                          if (!maxLocation || maxLocation === "inPlace") { -                            let hadView = expandedDocs.length === 1 && DocumentManager.Instance.getDocumentView(expandedProtoDocs[0], this.props.ContainingCollectionView); +                            let hadView = expandedDocs.length === 1 && DocumentManager.Instance.getDocumentView(expandedDocs[0], this.props.ContainingCollectionView);                              let wasMinimized = !hadView && expandedDocs.reduce((min, d) => !min && !BoolCast(d.IsMinimized, false), false);                              expandedDocs.forEach(maxDoc => Doc.GetProto(maxDoc).isMinimized = false); -                            let hasView = expandedDocs.length === 1 && DocumentManager.Instance.getDocumentView(expandedProtoDocs[0], this.props.ContainingCollectionView); +                            let hasView = expandedDocs.length === 1 && DocumentManager.Instance.getDocumentView(expandedDocs[0], this.props.ContainingCollectionView);                              if (!hasView) {                                  this.props.addDocument && expandedDocs.forEach(async maxDoc => this.props.addDocument!(getDispDoc(maxDoc), false));                              } -                            expandedProtoDocs.forEach(maxDoc => maxDoc.isMinimized = wasMinimized); +                            expandedDocs.forEach(maxDoc => maxDoc.isMinimized = wasMinimized);                          }                      }                      if (maxLocation && maxLocation !== "inPlace" && CollectionDockingView.Instance) { @@ -341,7 +344,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu                          }                      } else {                          let scrpt = this.props.ScreenToLocalTransform().scale(this.props.ContentScaling()).inverse().transformPoint(NumCast(this.Document.width) / 2, NumCast(this.Document.height) / 2); -                        this.collapseTargetsToPoint(scrpt, expandedProtoDocs); +                        this.collapseTargetsToPoint(scrpt, expandedDocs);                      }                  }                  else if (linkedDocs.length) { @@ -503,7 +506,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu      @undoBatch      @action      freezeNativeDimensions = (): void => { -        let proto = Doc.GetProto(this.props.Document); +        let proto = this.props.Document.isTemplate ? this.props.Document : Doc.GetProto(this.props.Document);          if (proto.ignoreAspect === undefined && !proto.nativeWidth) {              proto.nativeWidth = this.props.PanelWidth();              proto.nativeHeight = this.props.PanelHeight(); @@ -511,6 +514,11 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu          }          proto.ignoreAspect = !BoolCast(proto.ignoreAspect, false);      } +    @undoBatch +    @action +    makeBackground = (): void => { +        this.props.Document.isBackground = true; +    }      @undoBatch      @action @@ -541,6 +549,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu          cm.addItem({ description: BoolCast(this.props.Document.ignoreAspect, false) || !this.props.Document.nativeWidth || !this.props.Document.nativeHeight ? "Freeze" : "Unfreeze", event: this.freezeNativeDimensions, icon: "edit" });          cm.addItem({ description: "Pin to Pres", event: () => PresentationView.Instance.PinDoc(this.props.Document), icon: "map-pin" });          cm.addItem({ description: BoolCast(this.props.Document.lockedPosition) ? "Unlock Pos" : "Lock Pos", event: this.toggleLockPosition, icon: BoolCast(this.props.Document.lockedPosition) ? "unlock" : "lock" }); +        cm.addItem({ description: "Make Background", event: this.makeBackground, icon: BoolCast(this.props.Document.lockedPosition) ? "unlock" : "lock" });          cm.addItem({ description: this.props.Document.isButton ? "Remove Button" : "Make Button", event: this.makeBtnClicked, icon: "concierge-bell" });          cm.addItem({              description: "Make Portal", event: () => { @@ -553,20 +562,22 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu                  this.props.removeDocument && this.props.removeDocument(this.props.Document);              }, icon: "window-restore"          }); -        cm.addItem({ -            description: "Find aliases", event: async () => { -                const aliases = await SearchUtil.GetAliasesOfDocument(this.props.Document); -                this.props.addDocTab && this.props.addDocTab(Docs.Create.SchemaDocument(["title"], aliases, {}), undefined, "onRight"); // bcz: dataDoc? -            }, icon: "search" -        }); +        // cm.addItem({ +        //     description: "Find aliases", event: async () => { +        //         const aliases = await SearchUtil.GetAliasesOfDocument(this.props.Document); +        //         this.props.addDocTab && this.props.addDocTab(Docs.Create.SchemaDocument(["title"], aliases, {}), undefined, "onRight"); // bcz: dataDoc? +        //     }, icon: "search" +        // });          if (this.props.Document.detailedLayout && !this.props.Document.isTemplate) {              cm.addItem({ description: "Toggle detail", event: () => Doc.ToggleDetailLayout(this.props.Document), icon: "image" });          } -        cm.addItem({ description: "Add Repl", event: () => OverlayView.Instance.addWindow(<ScriptingRepl />, { x: 300, y: 100, width: 200, height: 200, title: "Scripting REPL" }) }); +        cm.addItem({ description: "Add Repl", icon: "laptop-code", event: () => OverlayView.Instance.addWindow(<ScriptingRepl />, { x: 300, y: 100, width: 200, height: 200, title: "Scripting REPL" }) });          cm.addItem({ description: "Center View", event: () => this.props.focus(this.props.Document, false), icon: "crosshairs" });          cm.addItem({ description: "Zoom to Document", event: () => this.props.focus(this.props.Document, true), icon: "search" }); -        cm.addItem({ description: "Copy URL", event: () => Utils.CopyText(Utils.prepend("/doc/" + this.props.Document[Id])), icon: "link" }); -        cm.addItem({ description: "Copy ID", event: () => Utils.CopyText(this.props.Document[Id]), icon: "fingerprint" }); +        if (!ClientUtils.RELEASE) { +            cm.addItem({ description: "Copy URL", event: () => Utils.CopyText(Utils.prepend("/doc/" + this.props.Document[Id])), icon: "link" }); +            cm.addItem({ description: "Copy ID", event: () => Utils.CopyText(this.props.Document[Id]), icon: "fingerprint" }); +        }          cm.addItem({ description: "Delete", event: this.deleteClicked, icon: "trash" });          type User = { email: string, userDocumentId: string };          let usersMenu: ContextMenuProps[] = []; @@ -608,7 +619,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu      }      onPointerEnter = (e: React.PointerEvent): void => { this.props.Document.libraryBrush = true; }; -    onPointerLeave = (e: React.PointerEvent): void => { this.props.Document.libraryBrush = undefined; }; +    onPointerLeave = (e: React.PointerEvent): void => { this.props.Document.libraryBrush = false; };      isSelected = () => SelectionManager.IsSelected(this);      @action select = (ctrlPressed: boolean) => { SelectionManager.SelectDoc(this, ctrlPressed); }; @@ -619,36 +630,42 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu          return (<DocumentContentsView {...this.props} isSelected={this.isSelected} select={this.select} selectOnLoad={this.props.selectOnLoad} layoutKey={"layout"} DataDoc={this.dataDoc} />);      } +    get layoutDoc() { +        // if this document's layout field contains a document (ie, a rendering template), then we will use that +        // 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 = this.props.Document.layout instanceof Doc ? StrCast(this.props.Document.layout.backgroundColor) : this.Document.backgroundColor; -        let foregroundColor = StrCast(this.props.Document.layout instanceof Doc ? this.props.Document.layout.color : this.props.Document.color); +        let backgroundColor = StrCast(this.layoutDoc.backgroundColor); +        let foregroundColor = StrCast(this.layoutDoc.color);          var nativeWidth = this.nativeWidth > 0 ? `${this.nativeWidth}px` : "100%";          var nativeHeight = BoolCast(this.props.Document.ignoreAspect) ? this.props.PanelHeight() / this.props.ContentScaling() : this.nativeHeight > 0 ? `${this.nativeHeight}px` : "100%"; -        let showOverlays = this.props.showOverlays ? this.props.showOverlays(this.props.Document) : undefined; -        let showTitle = showOverlays && showOverlays.title ? showOverlays.title : StrCast(this.props.Document.showTitle); -        let showCaption = showOverlays && showOverlays.caption ? showOverlays.caption : StrCast(this.props.Document.showCaption); -        let templates = Cast(this.props.Document.templates, listSpec("string")); -        if (templates instanceof List) { +        let showOverlays = this.props.showOverlays ? this.props.showOverlays(this.layoutDoc) : undefined; +        let showTitle = showOverlays && showOverlays.title !== "undefined" ? showOverlays.title : StrCast(this.layoutDoc.showTitle); +        let showCaption = showOverlays && showOverlays.caption !== "undefined" ? showOverlays.caption : StrCast(this.layoutDoc.showCaption); +        let templates = Cast(this.layoutDoc.templates, listSpec("string")); +        if (!showOverlays && templates instanceof List) {              templates.map(str => {                  if (str.indexOf("{props.Document.title}") !== -1) showTitle = "title";                  if (str.indexOf("fieldKey={\"caption\"}") !== -1) showCaption = "caption";              });          } -        let showTextTitle = showTitle && StrCast(this.props.Document.layout).startsWith("<FormattedTextBox") || (this.props.Document.layout instanceof Doc && StrCast(this.props.Document.layout.layout).startsWith("<FormattedTextBox")) ? showTitle : undefined; +        let showTextTitle = showTitle && StrCast(this.layoutDoc.layout).startsWith("<FormattedTextBox") ? showTitle : undefined;          return (              <div className={`documentView-node${this.topMost ? "-topmost" : ""}`}                  ref={this._mainCont}                  style={{ +                    pointerEvents: this.layoutDoc.isBackground ? "none" : "all",                      color: foregroundColor,                      outlineColor: "maroon",                      outlineStyle: "dashed", -                    outlineWidth: BoolCast(this.props.Document.libraryBrush) && !StrCast(this.props.Document.borderRounding) ? +                    outlineWidth: BoolCast(this.layoutDoc.libraryBrush) && !StrCast(Doc.GetProto(this.props.Document).borderRounding) ?                          `${this.props.ScreenToLocalTransform().Scale}px` : "0px", -                    border: BoolCast(this.props.Document.libraryBrush) && StrCast(this.props.Document.borderRounding) ? +                    border: BoolCast(this.layoutDoc.libraryBrush) && StrCast(Doc.GetProto(this.props.Document).borderRounding) ?                          `dashed maroon ${this.props.ScreenToLocalTransform().Scale}px` : undefined,                      borderRadius: "inherit",                      background: backgroundColor, @@ -663,22 +680,23 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu                  {!showTitle && !showCaption ? this.contents :                      <div style={{ position: "absolute", display: "inline-block", width: "100%", height: "100%", pointerEvents: "none" }}> -                        <div style={{ width: "100%", height: showTextTitle ? "calc(100% - 25px)" : "100%", display: "inline-block", position: "absolute", top: showTextTitle ? "25px" : undefined }}> +                        <div style={{ width: "100%", height: showTextTitle ? "calc(100% - 33px)" : "100%", display: "inline-block", position: "absolute", top: showTextTitle ? "29px" : undefined }}>                              {this.contents}                          </div>                          {!showTitle ? (null) :                              <div style={{ -                                position: showTextTitle ? "relative" : "absolute", top: 0, textAlign: "center", textOverflow: "ellipsis", whiteSpace: "pre", -                                pointerEvents: "all", +                                position: showTextTitle ? "relative" : "absolute", top: 0, padding: "4px", textAlign: "center", textOverflow: "ellipsis", whiteSpace: "pre", +                                pointerEvents: SelectionManager.GetIsDragging() ? "none" : "all",                                  overflow: "hidden", width: `${100 * this.props.ContentScaling()}%`, height: 25, background: "rgba(0, 0, 0, .4)", color: "white",                                  transformOrigin: "top left", transform: `scale(${1 / this.props.ContentScaling()})`                              }}>                                  <EditableView -                                    contents={this.props.Document[showTitle]} +                                    contents={this.layoutDoc[showTitle]}                                      display={"block"}                                      height={72} -                                    GetValue={() => StrCast(this.props.Document[showTitle])} -                                    SetValue={(value: string) => (Doc.GetProto(this.props.Document)[showTitle] = value) ? true : true} +                                    fontSize={12} +                                    GetValue={() => StrCast(this.layoutDoc[showTitle!])} +                                    SetValue={(value: string) => (Doc.GetProto(this.layoutDoc)[showTitle!] = value) ? true : true}                                  />                              </div>                          }  | 
