diff options
Diffstat (limited to 'src/client/views/nodes')
| -rw-r--r-- | src/client/views/nodes/CollectionFreeFormDocumentView.tsx | 22 | ||||
| -rw-r--r-- | src/client/views/nodes/DocumentContentsView.tsx | 3 | ||||
| -rw-r--r-- | src/client/views/nodes/DocumentView.scss | 17 | ||||
| -rw-r--r-- | src/client/views/nodes/DocumentView.tsx | 109 | ||||
| -rw-r--r-- | src/client/views/nodes/FieldView.tsx | 9 | ||||
| -rw-r--r-- | src/client/views/nodes/FormattedTextBox.tsx | 4 | ||||
| -rw-r--r-- | src/client/views/nodes/IconBox.scss | 12 | ||||
| -rw-r--r-- | src/client/views/nodes/IconBox.tsx | 45 | ||||
| -rw-r--r-- | src/client/views/nodes/ImageBox.tsx | 8 | ||||
| -rw-r--r-- | src/client/views/nodes/KeyValuePair.tsx | 2 |
10 files changed, 184 insertions, 47 deletions
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 8cf7a0dd2..1d42b3899 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -17,7 +17,7 @@ export class CollectionFreeFormDocumentView extends React.Component<CollectionFr @computed get transform(): string { - return `scale(${this.props.ContentScaling()}, ${this.props.ContentScaling()}) translate(${this.props.Document.GetNumber(KeyStore.X, 0)}px, ${this.props.Document.GetNumber(KeyStore.Y, 0)}px) scale(${this.zoom}, ${this.zoom}) `; + return `scale(${this.props.ContentScaling()}, ${this.props.ContentScaling()}) translate(${this.X}px, ${this.Y}px) scale(${this.zoom}, ${this.zoom}) `; } @computed get zoom(): number { return 1 / this.props.Document.GetNumber(KeyStore.Zoom, 1); } @@ -45,14 +45,20 @@ export class CollectionFreeFormDocumentView extends React.Component<CollectionFr this.props.Document.SetData(KeyStore.ZIndex, h, NumberField); } + get X() { + return this.props.Document.GetNumber(KeyStore.X, 0); + } + get Y() { + return this.props.Document.GetNumber(KeyStore.Y, 0); + } getTransform = (): Transform => this.props.ScreenToLocalTransform() - .translate(-this.props.Document.GetNumber(KeyStore.X, 0), -this.props.Document.GetNumber(KeyStore.Y, 0)) + .translate(-this.X, -this.Y) .scale(1 / this.contentScaling()).scale(1 / this.zoom) contentScaling = () => this.nativeWidth > 0 ? this.width / this.nativeWidth : 1; - panelWidth = () => this.props.Document.GetBoolean(KeyStore.Minimized, false) ? 10 : this.props.PanelWidth(); - panelHeight = () => this.props.Document.GetBoolean(KeyStore.Minimized, false) ? 10 : this.props.PanelHeight(); + panelWidth = () => this.props.PanelWidth(); + panelHeight = () => this.props.PanelHeight(); @computed get docView() { @@ -66,22 +72,22 @@ export class CollectionFreeFormDocumentView extends React.Component<CollectionFr render() { let zoomFade = 1; - // //var zoom = doc.GetNumber(KeyStore.Zoom, 1); - // let transform = (this.props.ScreenToLocalTransform().scale(this.props.ContentScaling())).inverse(); + //var zoom = doc.GetNumber(KeyStore.Zoom, 1); + // let transform = this.getTransform().scale(this.contentScaling()).inverse(); // var [sptX, sptY] = transform.transformPoint(0, 0); // let [bptX, bptY] = transform.transformPoint(this.props.PanelWidth(), this.props.PanelHeight()); // let w = bptX - sptX; // //zoomFade = area < 100 || area > 800 ? Math.max(0, Math.min(1, 2 - 5 * (zoom < this.scale ? this.scale / zoom : zoom / this.scale))) : 1; // let fadeUp = .75 * 1800; // let fadeDown = .075 * 1800; - // zoomFade = w < fadeDown || w > fadeUp ? Math.max(0, Math.min(1, 2 - (w < fadeDown ? fadeDown / w : w / fadeUp))) : 1; + // zoomFade = w < fadeDown /* || w > fadeUp */ ? Math.max(0, Math.min(1, 2 - (w < fadeDown ? fadeDown / w : w / fadeUp))) : 1; return ( <div className="collectionFreeFormDocumentView-container" ref={this._mainCont} style={{ opacity: zoomFade, transformOrigin: "left top", transform: this.transform, - pointerEvents: "all", + pointerEvents: (zoomFade < 0.09 ? "none" : "all"), width: this.width, height: this.height, position: "absolute", diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx index 76f852601..07599c345 100644 --- a/src/client/views/nodes/DocumentContentsView.tsx +++ b/src/client/views/nodes/DocumentContentsView.tsx @@ -15,6 +15,7 @@ import { DocumentViewProps } from "./DocumentView"; import "./DocumentView.scss"; import { FormattedTextBox } from "./FormattedTextBox"; import { ImageBox } from "./ImageBox"; +import { IconBox } from "./IconBox"; import { KeyValueBox } from "./KeyValueBox"; import { PDFBox } from "./PDFBox"; import { VideoBox } from "./VideoBox"; @@ -62,7 +63,7 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & { return <p>Error loading layout keys</p>; } return <JsxParser - components={{ FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView, CollectionPDFView, CollectionVideoView, WebBox, KeyValueBox, PDFBox, VideoBox, AudioBox, HistogramBox }} + components={{ FormattedTextBox, ImageBox, IconBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView, CollectionPDFView, CollectionVideoView, WebBox, KeyValueBox, PDFBox, VideoBox, AudioBox, HistogramBox }} bindings={this.CreateBindings()} jsx={this.layout} showWarnings={true} diff --git a/src/client/views/nodes/DocumentView.scss b/src/client/views/nodes/DocumentView.scss index 690ee50e8..7c72fb6e6 100644 --- a/src/client/views/nodes/DocumentView.scss +++ b/src/client/views/nodes/DocumentView.scss @@ -4,7 +4,7 @@ position: inherit; top: 0; left:0; - background: $light-color; //overflow: hidden; + // background: $light-color; //overflow: hidden; transform-origin: left top; &.minimized { @@ -13,7 +13,6 @@ } .top { - background: #232323; height: 20px; cursor: pointer; } @@ -31,18 +30,4 @@ } .documentView-node-topmost { background: white; -} - -.minimized-box { - height: 10px; - width: 10px; - border-radius: 2px; - background: $dark-color; - transform-origin: left top; -} - -.minimized-box:hover { - background: $main-accent; - transform: scale(1.15); - cursor: pointer; }
\ No newline at end of file diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 4f7909692..c06fe4c8d 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -36,12 +36,11 @@ export interface DocumentViewProps { focus: (doc: Document) => void; selectOnLoad: boolean; parentActive: () => boolean; - onActiveChanged: (isActive: boolean) => void; + whenActiveChanged: (isActive: boolean) => void; } const schema = createSchema({ layout: "string", - minimized: "boolean", nativeWidth: "number", nativeHeight: "number", backgroundColor: "string" @@ -136,7 +135,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu if (Math.abs(this._downX - e.clientX) > 3 || Math.abs(this._downY - e.clientY) > 3) { document.removeEventListener("pointermove", this.onPointerMove); document.removeEventListener("pointerup", this.onPointerUp); - if (!this.topMost || e.buttons === 2 || e.altKey) { + if (!e.altKey && (!this.topMost || e.buttons === 2)) { this.startDragging(this._downX, this._downY, e.ctrlKey || e.altKey); } } @@ -147,10 +146,19 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu document.removeEventListener("pointermove", this.onPointerMove); document.removeEventListener("pointerup", this.onPointerUp); e.stopPropagation(); - if (!SelectionManager.IsSelected(this) && e.button !== 2 && - Math.abs(e.clientX - this._downX) < 4 && Math.abs(e.clientY - this._downY) < 4) { - SelectionManager.SelectDoc(this, e.ctrlKey); - } + if (!SelectionManager.IsSelected(this) && e.button !== 2) + if (Math.abs(e.clientX - this._downX) < 4 && Math.abs(e.clientY - this._downY) < 4) { + if (this.props.Document.Get(KeyStore.MaximizedDoc) instanceof Document) { + this.props.Document.GetAsync(KeyStore.MaximizedDoc, maxdoc => { + if (maxdoc instanceof Document) { + this.props.addDocument && this.props.addDocument(maxdoc, false); + this.toggleMinimize(maxdoc, this.props.Document); + } + }); + } else { + SelectionManager.SelectDoc(this, e.ctrlKey); + } + } } stopPropagation = (e: React.SyntheticEvent) => { e.stopPropagation(); @@ -179,10 +187,84 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15); } + @action createIcon = (layoutString: string): Document => { + let iconDoc = Documents.IconDocument(layoutString); + iconDoc.SetBoolean(KeyStore.IsMinimized, false); + iconDoc.SetNumber(KeyStore.NativeWidth, 0); + iconDoc.SetNumber(KeyStore.NativeHeight, 0); + iconDoc.Set(KeyStore.Prototype, this.props.Document); + iconDoc.Set(KeyStore.MaximizedDoc, this.props.Document); + this.props.Document.Set(KeyStore.MinimizedDoc, iconDoc); + this.props.addDocument && this.props.addDocument(iconDoc, false); + return iconDoc; + } + + animateTransition(icon: number[], targ: number[], width: number, height: number, stime: number, target: Document, maximizing: boolean) { + setTimeout(() => { + let now = Date.now(); + let progress = Math.min(1, (now - stime) / 200); + let pval = maximizing ? + [icon[0] + (targ[0] - icon[0]) * progress, icon[1] + (targ[1] - icon[1]) * progress] : + [targ[0] + (icon[0] - targ[0]) * progress, targ[1] + (icon[1] - targ[1]) * progress]; + target.SetNumber(KeyStore.Width, maximizing ? 25 + (width - 25) * progress : width + (25 - width) * progress); + target.SetNumber(KeyStore.Height, maximizing ? 25 + (height - 25) * progress : height + (25 - height) * progress); + target.SetNumber(KeyStore.X, pval[0]); + target.SetNumber(KeyStore.Y, pval[1]); + if (now < stime + 200) { + this.animateTransition(icon, targ, width, height, stime, target, maximizing); + } + else { + if (!maximizing) { + target.SetBoolean(KeyStore.IsMinimized, true); + target.SetNumber(KeyStore.X, targ[0]); + target.SetNumber(KeyStore.Y, targ[1]); + target.SetNumber(KeyStore.Width, width); + target.SetNumber(KeyStore.Height, height); + } + this._completed = true; + } + }, + 2); + } + + _completed = true; + @action - public minimize = (): void => { - this.props.Document.SetBoolean(KeyStore.Minimized, true); + public toggleMinimize = (maximized: Document, minim: Document): void => { SelectionManager.DeselectAll(); + if (maximized instanceof Document && this._completed) { + this._completed = false; + let minimized = maximized.GetBoolean(KeyStore.IsMinimized, false); + maximized.SetBoolean(KeyStore.IsMinimized, false); + this.animateTransition( + [minim.GetNumber(KeyStore.X, 0), minim.GetNumber(KeyStore.Y, 0)], + [maximized.GetNumber(KeyStore.X, 0), maximized.GetNumber(KeyStore.Y, 0)], + maximized.GetNumber(KeyStore.Width, 0), maximized.GetNumber(KeyStore.Height, 0), + Date.now(), maximized, minimized); + } + } + + @action + public minimize = (): void => { + this.props.Document.GetAsync(KeyStore.MinimizedDoc, mindoc => { + if (mindoc === undefined) { + this.props.Document.GetAsync(KeyStore.BackgroundLayout, field => { + if (field instanceof TextField) { + this.toggleMinimize(this.props.Document, this.createIcon(field.Data)); + } + else this.props.Document.GetAsync(KeyStore.Layout, field => { + if (field instanceof TextField) { + this.createIcon(field.Data); + this.toggleMinimize(this.props.Document, this.createIcon(field.Data)); + } + }); + }); + } + else if (mindoc instanceof Document) { + this.props.addDocument && this.props.addDocument(mindoc, false); + this.toggleMinimize(this.props.Document, mindoc); + } + }); } @undoBatch @@ -250,7 +332,6 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu } e.preventDefault(); - !this.isMinimized() && ContextMenu.Instance.addItem({ description: "Minimize", event: this.minimize }); ContextMenu.Instance.addItem({ description: "Full Screen", event: this.fullScreenClicked }); ContextMenu.Instance.addItem({ description: "Fields", event: this.fieldsClicked }); ContextMenu.Instance.addItem({ description: "Center", event: () => this.props.focus(this.props.Document) }); @@ -265,9 +346,6 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu } } - @action - expand = () => this.Document.minimized = false - isMinimized = () => FieldValue(this.Document.minimized) || false; isSelected = () => SelectionManager.IsSelected(this); select = (ctrlPressed: boolean) => SelectionManager.SelectDoc(this, ctrlPressed); @@ -275,15 +353,12 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu @computed get nativeHeight() { return FieldValue(this.Document.nativeHeight) || 0; } @computed get contents() { return (<DocumentContentsView {...this.props} isSelected={this.isSelected} select={this.select} layoutKey={KeyStore.Layout} />); } + render() { var scaling = this.props.ContentScaling(); var nativeHeight = this.nativeHeight > 0 ? this.nativeHeight.toString() + "px" : "100%"; var nativeWidth = this.nativeWidth > 0 ? this.nativeWidth.toString() + "px" : "100%"; - if (this.isMinimized()) { - return <div className="minimized-box" ref={this._mainCont} onClick={this.expand} onDrop={this.onDrop} - style={{ transform: `scale(${scaling} , ${scaling})` }} onPointerDown={this.onPointerDown} />; - } return ( <div className={`documentView-node${this.props.isTopMost ? "-topmost" : ""}`} ref={this._mainCont} diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx index ebd25f937..93e385821 100644 --- a/src/client/views/nodes/FieldView.tsx +++ b/src/client/views/nodes/FieldView.tsx @@ -23,6 +23,8 @@ import { returnFalse, emptyDocFunction, emptyFunction, returnOne } from "../../. import { CollectionView } from "../collections/CollectionView"; import { CollectionPDFView } from "../collections/CollectionPDFView"; import { CollectionVideoView } from "../collections/CollectionVideoView"; +import { IconField } from "../../../fields/IconFIeld"; +import { IconBox } from "./IconBox"; // @@ -43,7 +45,7 @@ export interface FieldViewProps { moveDocument?: (document: Document, targetCollection: Document, addDocument: (document: Document) => boolean) => boolean; ScreenToLocalTransform: () => Transform; active: () => boolean; - onActiveChanged: (isActive: boolean) => void; + whenActiveChanged: (isActive: boolean) => void; focus: (doc: Document) => void; } @@ -72,6 +74,9 @@ export class FieldView extends React.Component<FieldViewProps> { else if (field instanceof ImageField) { return <ImageBox {...this.props} />; } + else if (field instanceof IconField) { + return <IconBox {...this.props} />; + } else if (field instanceof VideoField) { return <VideoBox {...this.props} />; } @@ -95,7 +100,7 @@ export class FieldView extends React.Component<FieldViewProps> { layoutKey={KeyStore.Layout} ContainingCollectionView={this.props.ContainingCollectionView} parentActive={this.props.active} - onActiveChanged={this.props.onActiveChanged} /> + whenActiveChanged={this.props.whenActiveChanged} /> ); } else if (field instanceof ListField) { diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index bff8ca7a4..639dae30a 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -19,6 +19,7 @@ import { MainOverlayTextBox } from "../MainOverlayTextBox"; import { FieldView, FieldViewProps } from "./FieldView"; import "./FormattedTextBox.scss"; import React = require("react"); +import { SelectionManager } from "../../util/SelectionManager"; const { buildMenuItems } = require("prosemirror-example-setup"); const { menuBar } = require("prosemirror-menu"); @@ -251,6 +252,9 @@ export class FormattedTextBox extends React.Component<(FieldViewProps & Formatte } onKeyPress(e: React.KeyboardEvent) { + if (e.key == "Escape") { + SelectionManager.DeselectAll(); + } e.stopPropagation(); if (e.keyCode === 9) e.preventDefault(); // stop propagation doesn't seem to stop propagation of native keyboard events. diff --git a/src/client/views/nodes/IconBox.scss b/src/client/views/nodes/IconBox.scss new file mode 100644 index 000000000..ce0ee2e09 --- /dev/null +++ b/src/client/views/nodes/IconBox.scss @@ -0,0 +1,12 @@ + +@import "../globalCssVariables"; +.iconBox-container { + position: absolute; + left:0; + top:0; + svg { + width: 100% !important; + height: 100%; + background: white; + } +}
\ No newline at end of file diff --git a/src/client/views/nodes/IconBox.tsx b/src/client/views/nodes/IconBox.tsx new file mode 100644 index 000000000..9c90c0a0e --- /dev/null +++ b/src/client/views/nodes/IconBox.tsx @@ -0,0 +1,45 @@ +import React = require("react"); +import { library } from '@fortawesome/fontawesome-svg-core'; +import { faCaretUp, faFilePdf, faFilm, faImage, faObjectGroup, faStickyNote } from '@fortawesome/free-solid-svg-icons'; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { action, computed } from "mobx"; +import { observer } from "mobx-react"; +import { Document } from '../../../fields/Document'; +import { IconField } from "../../../fields/IconFIeld"; +import { KeyStore } from "../../../fields/KeyStore"; +import { SelectionManager } from "../../util/SelectionManager"; +import { FieldView, FieldViewProps } from './FieldView'; +import "./IconBox.scss"; + + +library.add(faCaretUp); +library.add(faObjectGroup); +library.add(faStickyNote); +library.add(faFilePdf); +library.add(faFilm); + +@observer +export class IconBox extends React.Component<FieldViewProps> { + public static LayoutString() { return FieldView.LayoutString(IconBox); } + + @computed get maximized() { return this.props.Document.GetT(KeyStore.MaximizedDoc, Document); } + @computed get layout(): string { return this.props.Document.GetData(this.props.fieldKey, IconField, "<p>Error loading layout data</p>" as string); } + @computed get minimizedIcon() { return IconBox.DocumentIcon(this.layout); } + + public static DocumentIcon(layout: string) { + let button = layout.indexOf("PDFBox") !== -1 ? faFilePdf : + layout.indexOf("ImageBox") !== -1 ? faImage : + layout.indexOf("Formatted") !== -1 ? faStickyNote : + layout.indexOf("Video") !== -1 ? faFilm : + layout.indexOf("Collection") !== -1 ? faObjectGroup : + faCaretUp; + return <FontAwesomeIcon icon={button} className="documentView-minimizedIcon" /> + } + + render() { + return ( + <div className="iconBox-container"> + {this.minimizedIcon} + </div>); + } +}
\ No newline at end of file diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 71b431b84..fd5381b77 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -38,7 +38,10 @@ export class ImageBox extends React.Component<FieldViewProps> { onLoad = (target: any) => { var h = this._imgRef.current!.naturalHeight; var w = this._imgRef.current!.naturalWidth; - if (this._photoIndex === 0) this.props.Document.SetNumber(KeyStore.NativeHeight, this.props.Document.GetNumber(KeyStore.NativeWidth, 0) * h / w); + if (this._photoIndex === 0) { + this.props.Document.SetNumber(KeyStore.NativeHeight, this.props.Document.GetNumber(KeyStore.NativeWidth, 0) * h / w); + this.props.Document.SetNumber(KeyStore.Height, this.props.Document.Width() * h / w); + } } @@ -65,7 +68,7 @@ export class ImageBox extends React.Component<FieldViewProps> { if (layout.indexOf(ImageBox.name) !== -1) { let imgData = this.props.Document.Get(KeyStore.Data); if (imgData instanceof ImageField && imgData) { - this.props.Document.Set(KeyStore.Data, new ListField([imgData])); + this.props.Document.SetOnPrototype(KeyStore.Data, new ListField([imgData])); } let imgList = this.props.Document.GetList(KeyStore.Data, [] as any[]); if (imgList) { @@ -137,6 +140,7 @@ export class ImageBox extends React.Component<FieldViewProps> { @action onDotDown(index: number) { this._photoIndex = index; + this.props.Document.SetNumber(KeyStore.CurPage, index); } dots(paths: string[]) { diff --git a/src/client/views/nodes/KeyValuePair.tsx b/src/client/views/nodes/KeyValuePair.tsx index 5d69f23b2..d480eb5af 100644 --- a/src/client/views/nodes/KeyValuePair.tsx +++ b/src/client/views/nodes/KeyValuePair.tsx @@ -48,7 +48,7 @@ export class KeyValuePair extends React.Component<KeyValuePairProps> { isTopMost: false, selectOnLoad: false, active: returnFalse, - onActiveChanged: emptyFunction, + whenActiveChanged: emptyFunction, ScreenToLocalTransform: Transform.Identity, focus: emptyDocFunction, }; |
