aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/views/DocumentDecorations.tsx41
-rw-r--r--src/client/views/Main.tsx1
-rw-r--r--src/client/views/collections/CollectionBaseView.tsx4
-rw-r--r--src/client/views/collections/CollectionDockingView.tsx1
-rw-r--r--src/client/views/collections/CollectionSchemaView.tsx3
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx1
-rw-r--r--src/client/views/nodes/CollectionFreeFormDocumentView.tsx174
-rw-r--r--src/client/views/nodes/DocumentView.tsx180
-rw-r--r--src/client/views/nodes/ImageBox.tsx5
9 files changed, 215 insertions, 195 deletions
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index d704b6c47..95910c7be 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -18,6 +18,7 @@ import React = require("react");
import { CompileScript } from "../util/Scripting";
import { IconBox } from "./nodes/IconBox";
import { FieldValue, Field } from "../../fields/Field";
+import { Documents } from "../documents/Documents";
const higflyout = require("@hig/flyout");
export const { anchorPoints } = higflyout;
export const Flyout = higflyout.default;
@@ -134,11 +135,12 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
@action
onBackgroundMove = (e: PointerEvent): void => {
let dragDocView = SelectionManager.SelectedDocuments()[0];
- const [left, top] = dragDocView.props.ScreenToLocalTransform().inverse().transformPoint(0, 0);
+ const [left, top] = dragDocView.props.ScreenToLocalTransform().scale(dragDocView.props.ContentScaling()).inverse().transformPoint(0, 0);
let dragData = new DragManager.DocumentDragData(SelectionManager.SelectedDocuments().map(dv => dv.props.Document));
+ const [xoff, yoff] = dragDocView.props.ScreenToLocalTransform().scale(dragDocView.props.ContentScaling()).transformDirection(e.x - left, e.y - top);
+ dragData.xOffset = xoff;
+ dragData.yOffset = yoff;
dragData.aliasOnDrop = false;
- dragData.xOffset = e.x - left;
- dragData.yOffset = e.y - top;
let move = SelectionManager.SelectedDocuments()[0].props.moveDocument;
dragData.moveDocument = move;
this.Interacting = this._dragging = true;
@@ -213,12 +215,39 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
this._minimizedX = snapped ? selDocPos[0] + 4 : e.clientX;
this._minimizedY = snapped ? selDocPos[1] - 18 : e.clientY;
let selectedDocs = SelectionManager.SelectedDocuments().map(sd => sd);
- Promise.all(selectedDocs.map(async selDoc => await selDoc.getIconDoc())).then(minDocSet =>
+ Promise.all(selectedDocs.map(async selDoc => await this.getIconDoc(selDoc))).then(minDocSet =>
this.moveIconDocs(SelectionManager.SelectedDocuments())
);
this._iconifying = snapped;
}
}
+
+
+ @action createIcon = (docView: DocumentView, layoutString: string): Document => {
+ let doc = docView.props.Document;
+ let iconDoc = Documents.IconDocument(layoutString);
+ iconDoc.SetText(KeyStore.Title, "ICON" + doc.Title)
+ iconDoc.SetBoolean(KeyStore.IsMinimized, false);
+ iconDoc.SetNumber(KeyStore.NativeWidth, 0);
+ iconDoc.SetNumber(KeyStore.NativeHeight, 0);
+ iconDoc.SetNumber(KeyStore.X, doc.GetNumber(KeyStore.X, 0));
+ iconDoc.SetNumber(KeyStore.Y, doc.GetNumber(KeyStore.Y, 0) - 24);
+ iconDoc.Set(KeyStore.Prototype, doc);
+ iconDoc.Set(KeyStore.MaximizedDoc, doc);
+ doc.Set(KeyStore.MinimizedDoc, iconDoc);
+ docView.props.addDocument && docView.props.addDocument(iconDoc, false);
+ return iconDoc;
+ }
+ @action
+ public getIconDoc = async (docView: DocumentView): Promise<Document | undefined> => {
+ let doc = docView.props.Document;
+ return await doc.GetTAsync(KeyStore.MinimizedDoc, Document).then(async mindoc =>
+ mindoc ? mindoc :
+ await doc.GetTAsync(KeyStore.BackgroundLayout, TextField).then(async field =>
+ (field instanceof TextField) ? this.createIcon(docView, field.Data) :
+ await doc.GetTAsync(KeyStore.Layout, TextField).then(field =>
+ (field instanceof TextField) ? this.createIcon(docView, field.Data) : undefined)));
+ }
@action
onMinimizeUp = (e: PointerEvent): void => {
e.stopPropagation();
@@ -226,7 +255,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
document.removeEventListener("pointermove", this.onMinimizeMove);
document.removeEventListener("pointerup", this.onMinimizeUp);
let selectedDocs = SelectionManager.SelectedDocuments().map(sd => sd);
- Promise.all(selectedDocs.map(async selDoc => await selDoc.getIconDoc())).then(minDocSet => {
+ Promise.all(selectedDocs.map(async selDoc => await this.getIconDoc(selDoc))).then(minDocSet => {
let minDocs = minDocSet.filter(minDoc => minDoc instanceof Document).map(minDoc => minDoc as Document);
minDocs.map(minDoc => {
minDoc.SetNumber(KeyStore.X, minDocs[0].GetNumber(KeyStore.X, 0));
@@ -238,7 +267,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
}
});
runInAction(() => this._minimizedX = this._minimizedY = 0);
- if (!this._iconifying) selectedDocs[0].toggleIcon();
+ if (!this._iconifying) selectedDocs[0].props.toggleMinimized();
this._iconifying = false;
});
}
diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx
index 09ef30f6b..934616aca 100644
--- a/src/client/views/Main.tsx
+++ b/src/client/views/Main.tsx
@@ -187,6 +187,7 @@ export class Main extends React.Component {
<div ref={measureRef} id="mainContent-div">
{!mainCont ? (null) :
<DocumentView Document={mainCont}
+ toggleMinimized={emptyFunction}
addDocument={undefined}
removeDocument={undefined}
ScreenToLocalTransform={Transform.Identity}
diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx
index 9ae2993be..962cb9b65 100644
--- a/src/client/views/collections/CollectionBaseView.tsx
+++ b/src/client/views/collections/CollectionBaseView.tsx
@@ -94,7 +94,6 @@ export class CollectionBaseView extends React.Component<CollectionViewProps> {
doc.SetOnPrototype(KeyStore.AnnotationOn, this.props.Document);
}
if (!this.createsCycle(doc, this.props.Document)) {
- doc.SetNumber(KeyStore.ZoomBasis, this.props.Document.GetNumber(KeyStore.Scale, 1));
let value = this.props.Document.Get(this.props.fieldKey) as ListField<Document>;
if (value) {
if (!value.Data.some(v => v.Id === doc.Id) || allowDuplicates) {
@@ -103,6 +102,9 @@ export class CollectionBaseView extends React.Component<CollectionViewProps> {
} else {
this.props.Document.Set(this.props.fieldKey, new ListField([doc]));
}
+ // set the ZoomBasis only if hasn't already been set -- bcz: maybe set/resetting the ZoomBasis should be a parameter to addDocument?
+ doc.GetTAsync(KeyStore.ZoomBasis, NumberField, field => !field &&
+ doc.SetNumber(KeyStore.ZoomBasis, this.props.Document.GetNumber(KeyStore.Scale, 1)));
}
return true;
// bcz: What is this code trying to do?
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index e4c647635..1ea18ed42 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -350,6 +350,7 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
<div className="collectionDockingView-content" ref={this._mainCont}
style={{ transform: `translate(${this.previewPanelCenteringOffset}px, 0px)` }}>
<DocumentView key={this._document!.Id} Document={this._document!}
+ toggleMinimized={emptyFunction}
addDocument={undefined}
removeDocument={undefined}
ContentScaling={this.contentScaling}
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 90077b053..cb7a67991 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -62,7 +62,7 @@ export class CollectionSchemaView extends CollectionSubView {
@computed get splitPercentage() { return this.props.Document.GetNumber(KeyStore.SchemaSplitPercentage, 0); }
@computed get columns() { return this.props.Document.GetList(KeyStore.ColumnsKey, [] as Key[]); }
- @computed get borderWidth() { return COLLECTION_BORDER_WIDTH; }
+ @computed get borderWidth() { return Number(COLLECTION_BORDER_WIDTH); }
renderCell = (rowProps: CellInfo) => {
let props: FieldViewProps = {
@@ -266,6 +266,7 @@ export class CollectionSchemaView extends CollectionSubView {
<div className="collectionSchemaView-previewRegion" style={{ width: `${this.previewRegionWidth}px` }}>
<div className="collectionSchemaView-previewDoc" style={{ transform: `translate(${this.previewPanelCenteringOffset}px, 0px)` }}>
<DocumentView Document={this.previewDocument} isTopMost={false} selectOnLoad={false}
+ toggleMinimized={emptyFunction}
addDocument={this.props.addDocument} removeDocument={this.props.removeDocument}
ScreenToLocalTransform={this.getPreviewTransform}
ContentScaling={this.previewContentScaling}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 117343ef3..56d54696d 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -247,6 +247,7 @@ export class CollectionFreeFormView extends CollectionSubView {
getDocumentViewProps(document: Document): DocumentViewProps {
return {
Document: document,
+ toggleMinimized: emptyFunction,
addDocument: this.props.addDocument,
removeDocument: this.props.removeDocument,
moveDocument: this.props.moveDocument,
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 9fa6a4f51..3a4425358 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -1,12 +1,17 @@
-import { computed, trace } from "mobx";
+import { computed, trace, action } from "mobx";
import { observer } from "mobx-react";
import { KeyStore } from "../../../fields/KeyStore";
import { NumberField } from "../../../fields/NumberField";
+import { Document } from "../../../fields/Document";
import { Transform } from "../../util/Transform";
import { DocumentView, DocumentViewProps } from "./DocumentView";
import "./DocumentView.scss";
import React = require("react");
import { OmitKeys } from "../../../Utils";
+import { SelectionManager } from "../../util/SelectionManager";
+import { ListField } from "../../../fields/ListField";
+import { BooleanField } from "../../../fields/BooleanField";
+import { matchedData } from "express-validator/filter";
export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps {
}
@@ -14,55 +19,48 @@ export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps {
@observer
export class CollectionFreeFormDocumentView extends React.Component<CollectionFreeFormDocumentViewProps> {
private _mainCont = React.createRef<HTMLDivElement>();
+ private _downX: number = 0;
+ private _downY: number = 0;
- @computed
- get transform(): string {
+ @computed get transform() {
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.ZoomBasis, 1); }
- @computed get zIndex(): number { return this.props.Document.GetNumber(KeyStore.ZIndex, 0); }
- @computed get width(): number { return this.props.Document.Width(); }
- @computed get height(): number { return this.props.Document.Height(); }
- @computed get nativeWidth(): number { return this.props.Document.GetNumber(KeyStore.NativeWidth, 0); }
- @computed get nativeHeight(): number { return this.props.Document.GetNumber(KeyStore.NativeHeight, 0); }
-
+ @computed get X() { return this.props.Document.GetNumber(KeyStore.X, 0); }
+ @computed get Y() { return this.props.Document.GetNumber(KeyStore.Y, 0); }
+ @computed get zoom() { return 1 / this.props.Document.GetNumber(KeyStore.ZoomBasis, 1); }
+ @computed get nativeWidth() { return this.props.Document.GetNumber(KeyStore.NativeWidth, 0); }
+ @computed get nativeHeight() { return this.props.Document.GetNumber(KeyStore.NativeHeight, 0); }
+ @computed get width() { return this.props.Document.Width(); }
+ @computed get height() { return this.props.Document.Height(); }
+ @computed get zIndex() { return this.props.Document.GetNumber(KeyStore.ZIndex, 0); }
set width(w: number) {
this.props.Document.SetData(KeyStore.Width, w, NumberField);
if (this.nativeWidth && this.nativeHeight) {
this.props.Document.SetNumber(KeyStore.Height, this.nativeHeight / this.nativeWidth * w);
}
}
-
set height(h: number) {
this.props.Document.SetData(KeyStore.Height, h, NumberField);
if (this.nativeWidth && this.nativeHeight) {
this.props.Document.SetNumber(KeyStore.Width, this.nativeWidth / this.nativeHeight * h);
}
}
-
set zIndex(h: number) {
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.X, -this.Y)
- .scale(1 / this.contentScaling()).scale(1 / this.zoom)
-
contentScaling = () => (this.nativeWidth > 0 ? this.width / this.nativeWidth : 1);
panelWidth = () => this.props.PanelWidth();
panelHeight = () => this.props.PanelHeight();
+ toggleMinimized = () => this.toggleIcon();
+ getTransform = (): Transform => this.props.ScreenToLocalTransform()
+ .translate(-this.X, -this.Y)
+ .scale(1 / this.contentScaling()).scale(1 / this.zoom)
@computed
get docView() {
return <DocumentView {...OmitKeys(this.props, ['zoomFade'])}
+ toggleMinimized={this.toggleMinimized}
ContentScaling={this.contentScaling}
ScreenToLocalTransform={this.getTransform}
PanelWidth={this.panelWidth}
@@ -70,30 +68,120 @@ export class CollectionFreeFormDocumentView extends React.Component<CollectionFr
/>;
}
+ animateBetweenIcon(first: boolean, 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 (first) {
+ target.SetBoolean(KeyStore.IsMinimized, false);
+ }
+ if (now < stime + 200) {
+ this.animateBetweenIcon(false, 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);
+ }
+ (target as any).isIconAnimating = false;
+ }
+ },
+ 2);
+ }
+ @action
+ public toggleIcon = async (): Promise<void> => {
+ SelectionManager.DeselectAll();
+ let isMinimized: boolean | undefined;
+ let minDoc = await this.props.Document.GetTAsync(KeyStore.MinimizedDoc, Document);
+ if (!minDoc) return;
+ let minimizedDocSet = await minDoc.GetTAsync(KeyStore.LinkTags, ListField);
+ if (!minimizedDocSet) return;
+ minimizedDocSet.Data.map(async minimizedDoc => {
+ if (minimizedDoc instanceof Document) {
+ this.props.addDocument && this.props.addDocument(minimizedDoc, false);
+ let maximizedDoc = await minimizedDoc.GetTAsync(KeyStore.MaximizedDoc, Document);
+ if (maximizedDoc instanceof Document && !(maximizedDoc as any).isIconAnimating) {
+ (maximizedDoc as any).isIconAnimating = true;
+ if (isMinimized === undefined) {
+ let maximizedDocMinimizedState = await maximizedDoc.GetTAsync(KeyStore.IsMinimized, BooleanField);
+ isMinimized = (maximizedDocMinimizedState && maximizedDocMinimizedState.Data) ? true : false;
+ }
+ let minx = await minimizedDoc.GetTAsync(KeyStore.X, NumberField);
+ let miny = await minimizedDoc.GetTAsync(KeyStore.Y, NumberField);
+ let maxx = await maximizedDoc.GetTAsync(KeyStore.X, NumberField);
+ let maxy = await maximizedDoc.GetTAsync(KeyStore.Y, NumberField);
+ let maxw = await maximizedDoc.GetTAsync(KeyStore.Width, NumberField);
+ let maxh = await maximizedDoc.GetTAsync(KeyStore.Height, NumberField);
+ if (minx !== undefined && miny !== undefined && maxx !== undefined && maxy !== undefined &&
+ maxw !== undefined && maxh !== undefined)
+ this.animateBetweenIcon(
+ true,
+ [minx.Data, miny.Data], [maxx.Data, maxy.Data], maxw.Data, maxh.Data,
+ Date.now(), maximizedDoc, isMinimized);
+ }
+
+ }
+ })
+ }
+ onPointerDown = (e: React.PointerEvent): void => {
+ e.stopPropagation();
+ this._downX = e.clientX;
+ this._downY = e.clientY;
+ document.removeEventListener("pointerup", this.onPointerUp);
+ document.addEventListener("pointerup", this.onPointerUp);
+ }
+ onPointerUp = (e: PointerEvent): void => {
+ document.removeEventListener("pointerup", this.onPointerUp);
+ e.stopPropagation();
+ if (Math.abs(e.clientX - this._downX) < 4 && Math.abs(e.clientY - this._downY) < 4) {
+ this.props.Document.GetTAsync(KeyStore.MaximizedDoc, Document).then(maxdoc => {
+ if (maxdoc instanceof Document) { // bcz: need a better way to associate behaviors with click events on widget-documents
+ SelectionManager.DeselectAll();
+ this.props.addDocument && this.props.addDocument(maxdoc, false);
+ this.toggleIcon();
+ }
+ });
+ }
+ }
+
render() {
+ let maximizedDoc = this.props.Document.GetT(KeyStore.MaximizedDoc, Document);
let zoomFade = 1;
//var zoom = doc.GetNumber(KeyStore.ZoomBasis, 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;
+ 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;
+ const screenWidth = 1800;
+ let fadeUp = .75 * screenWidth;
+ let fadeDown = (maximizedDoc ? .0075 : .075) * screenWidth;
+ 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: (zoomFade < 0.09 ? "none" : "all"),
- width: this.width,
- height: this.height,
- position: "absolute",
- zIndex: this.zIndex,
- backgroundColor: "transparent"
- }} >
+ <div className="collectionFreeFormDocumentView-container" ref={this._mainCont}
+ onPointerDown={this.onPointerDown}
+ style={{
+ opacity: zoomFade,
+ transformOrigin: "left top",
+ transform: this.transform,
+ pointerEvents: (zoomFade < 0.09 ? "none" : "all"),
+ width: this.width,
+ height: this.height,
+ position: "absolute",
+ zIndex: this.zIndex,
+ backgroundColor: "transparent"
+ }} >
{this.docView}
</div>
);
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 2f8ac9f20..8922e4b81 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -5,8 +5,6 @@ import { Field, Opt } from "../../../fields/Field";
import { Key } from "../../../fields/Key";
import { KeyStore } from "../../../fields/KeyStore";
import { ListField } from "../../../fields/ListField";
-import { NumberField } from "../../../fields/NumberField";
-import { TextField } from "../../../fields/TextField";
import { ServerUtils } from "../../../server/ServerUtil";
import { emptyFunction, Utils } from "../../../Utils";
import { Documents } from "../../documents/Documents";
@@ -40,6 +38,7 @@ export interface DocumentViewProps {
selectOnLoad: boolean;
parentActive: () => boolean;
whenActiveChanged: (isActive: boolean) => void;
+ toggleMinimized: () => void;
}
export interface JsxArgs extends DocumentViewProps {
Keys: { [name: string]: Key };
@@ -83,7 +82,6 @@ export function FakeJsxArgs(keys: string[], fields: string[] = []): JsxArgs {
@observer
export class DocumentView extends React.Component<DocumentViewProps> {
- static _incompleteAnimations: Map<string, boolean> = new Map<string, boolean>();
private _downX: number = 0;
private _downY: number = 0;
private _mainCont = React.createRef<HTMLDivElement>();
@@ -96,42 +94,16 @@ export class DocumentView extends React.Component<DocumentViewProps> {
@computed get layoutKeys(): Key[] { return this.props.Document.GetData(KeyStore.LayoutKeys, ListField, new Array<Key>()); }
@computed get layoutFields(): Key[] { return this.props.Document.GetData(KeyStore.LayoutFields, ListField, new Array<Key>()); }
- onPointerDown = (e: React.PointerEvent): void => {
- this._downX = e.clientX;
- this._downY = e.clientY;
- if (CollectionFreeFormView.RIGHT_BTN_DRAG && (e.button === 2 || (e.button === 0 && e.altKey)) && !this.isSelected()) {
- return;
- }
- if (e.shiftKey && e.buttons === 2) {
- if (this.props.isTopMost) {
- this.startDragging(e.pageX, e.pageY, e.altKey || e.ctrlKey);
- } else {
- CollectionDockingView.Instance.StartOtherDrag([this.props.Document], e);
- }
- e.stopPropagation();
- } else {
- let maxdoc = this.props.Document.GetT(KeyStore.MaximizedDoc, Document);
- if (this.active ||
- maxdoc instanceof Document // bcz: need a better way of allowing a document to handle pointer events when its not active (ie. be a top-level widget)
- ) {
- e.stopPropagation();
- document.removeEventListener("pointermove", this.onPointerMove);
- document.addEventListener("pointermove", this.onPointerMove);
- document.removeEventListener("pointerup", this.onPointerUp);
- document.addEventListener("pointerup", this.onPointerUp);
- }
- }
- }
-
+ @action
componentDidMount() {
if (this._mainCont.current) {
this._dropDisposer = DragManager.MakeDropTarget(this._mainCont.current, {
handlers: { drop: this.drop.bind(this) }
});
}
- runInAction(() => DocumentManager.Instance.DocumentViews.push(this));
+ DocumentManager.Instance.DocumentViews.push(this);
}
-
+ @action
componentDidUpdate() {
if (this._dropDisposer) {
this._dropDisposer();
@@ -142,12 +114,16 @@ export class DocumentView extends React.Component<DocumentViewProps> {
});
}
}
-
+ @action
componentWillUnmount() {
if (this._dropDisposer) {
this._dropDisposer();
}
- runInAction(() => DocumentManager.Instance.DocumentViews.splice(DocumentManager.Instance.DocumentViews.indexOf(this), 1));
+ DocumentManager.Instance.DocumentViews.splice(DocumentManager.Instance.DocumentViews.indexOf(this), 1);
+ }
+
+ stopPropagation = (e: React.SyntheticEvent) => {
+ e.stopPropagation();
}
startDragging(x: number, y: number, dropAliasOfDraggedDoc: boolean) {
@@ -168,43 +144,51 @@ export class DocumentView extends React.Component<DocumentViewProps> {
}
}
- onPointerMove = (e: PointerEvent): void => {
- if (e.cancelBubble) {
+ onPointerDown = (e: React.PointerEvent): void => {
+ this._downX = e.clientX;
+ this._downY = e.clientY;
+ if (CollectionFreeFormView.RIGHT_BTN_DRAG && (e.button === 2 || (e.button === 0 && e.altKey)) && !this.isSelected()) {
return;
}
- if (Math.abs(this._downX - e.clientX) > 3 || Math.abs(this._downY - e.clientY) > 3) {
+ if (e.shiftKey && e.buttons === 2) {
+ if (this.props.isTopMost) {
+ this.startDragging(e.pageX, e.pageY, e.altKey || e.ctrlKey);
+ } else {
+ CollectionDockingView.Instance.StartOtherDrag([this.props.Document], e);
+ }
+ e.stopPropagation();
+ } else if (this.active) {
document.removeEventListener("pointermove", this.onPointerMove);
+ document.addEventListener("pointermove", this.onPointerMove);
document.removeEventListener("pointerup", this.onPointerUp);
- if (!e.altKey && (!this.topMost || e.buttons === 2)) {
- this.startDragging(this._downX, this._downY, e.ctrlKey || e.altKey);
+ document.addEventListener("pointerup", this.onPointerUp);
+ }
+ }
+ onPointerMove = (e: PointerEvent): void => {
+ if (!e.cancelBubble) {
+ 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 (!e.altKey && (!this.topMost || e.buttons === 2)) {
+ this.startDragging(this._downX, this._downY, e.ctrlKey || e.altKey);
+ }
}
+ e.stopPropagation();
+ e.preventDefault();
}
- e.stopPropagation();
- e.preventDefault();
}
onPointerUp = (e: PointerEvent): void => {
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) {
- this.props.Document.GetTAsync(KeyStore.MaximizedDoc, Document).then(maxdoc => {
- if (maxdoc instanceof Document) { // bcz: need a better way to associate behaviors with click events on widget-documents
- this.props.addDocument && this.props.addDocument(maxdoc, false);
- this.toggleIcon();
- } else
- SelectionManager.SelectDoc(this, e.ctrlKey);
- });
+ SelectionManager.SelectDoc(this, e.ctrlKey);
}
}
- stopPropagation = (e: React.SyntheticEvent) => {
- e.stopPropagation();
- }
deleteClicked = (): void => {
this.props.removeDocument && this.props.removeDocument(this.props.Document);
}
-
fieldsClicked = (e: React.MouseEvent): void => {
let kvp = Documents.KVPDocument(this.props.Document, { width: 300, height: 300 });
CollectionDockingView.Instance.AddRightSplit(kvp);
@@ -215,7 +199,6 @@ export class DocumentView extends React.Component<DocumentViewProps> {
ContextMenu.Instance.addItem({ description: "Close Full Screen", event: this.closeFullScreenClicked });
ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15);
}
-
closeFullScreenClicked = (e: React.MouseEvent): void => {
CollectionDockingView.Instance.CloseFullScreen();
ContextMenu.Instance.clearItems();
@@ -223,92 +206,6 @@ export class DocumentView extends React.Component<DocumentViewProps> {
ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15);
}
- @action createIcon = (layoutString: string): Document => {
- let iconDoc = Documents.IconDocument(layoutString);
- iconDoc.SetText(KeyStore.Title, "ICON" + this.props.Document.Title)
- iconDoc.SetBoolean(KeyStore.IsMinimized, false);
- iconDoc.SetNumber(KeyStore.NativeWidth, 0);
- iconDoc.SetNumber(KeyStore.NativeHeight, 0);
- iconDoc.SetNumber(KeyStore.X, this.props.Document.GetNumber(KeyStore.X, 0));
- iconDoc.SetNumber(KeyStore.Y, this.props.Document.GetNumber(KeyStore.Y, 0) - 24);
- 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;
- }
-
- animateBetweenIcon(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.animateBetweenIcon(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);
- }
- DocumentView._incompleteAnimations.set(target.Id, false);
- }
- },
- 2);
- }
-
- @action
- public toggleIcon = async (): Promise<void> => {
- SelectionManager.DeselectAll();
- let isMinimized: boolean | undefined;
- let minDoc = await this.props.Document.GetTAsync(KeyStore.MinimizedDoc, Document);
- if (!minDoc) return;
- let minimizedDocSet = await minDoc.GetTAsync(KeyStore.LinkTags, ListField);
- if (!minimizedDocSet) return;
- minimizedDocSet.Data.map(async minimizedDoc => {
- if (minimizedDoc instanceof Document) {
- this.props.addDocument && this.props.addDocument(minimizedDoc, false);
- let maximizedDoc = await minimizedDoc.GetTAsync(KeyStore.MaximizedDoc, Document);
- if (maximizedDoc instanceof Document && !DocumentView._incompleteAnimations.get(maximizedDoc.Id)) {
- DocumentView._incompleteAnimations.set(maximizedDoc.Id, true);
- isMinimized = isMinimized === undefined ? maximizedDoc.GetBoolean(KeyStore.IsMinimized, false) : isMinimized;
- maximizedDoc.SetBoolean(KeyStore.IsMinimized, false);
- let minx = await minimizedDoc.GetTAsync(KeyStore.X, NumberField);
- let miny = await minimizedDoc.GetTAsync(KeyStore.Y, NumberField);
- let maxx = await maximizedDoc.GetTAsync(KeyStore.X, NumberField);
- let maxy = await maximizedDoc.GetTAsync(KeyStore.Y, NumberField);
- let maxw = await maximizedDoc.GetTAsync(KeyStore.Width, NumberField);
- let maxh = await maximizedDoc.GetTAsync(KeyStore.Height, NumberField);
- if (minx !== undefined && miny !== undefined && maxx !== undefined && maxy !== undefined &&
- maxw !== undefined && maxh !== undefined)
- this.animateBetweenIcon(
- [minx.Data, miny.Data], [maxx.Data, maxy.Data], maxw.Data, maxh.Data,
- Date.now(), maximizedDoc, isMinimized);
- }
-
- }
- })
- }
-
- @action
- public getIconDoc = async (): Promise<Document | undefined> => {
- return await this.props.Document.GetTAsync(KeyStore.MinimizedDoc, Document).then(async mindoc =>
- mindoc ? mindoc :
- await this.props.Document.GetTAsync(KeyStore.BackgroundLayout, TextField).then(async field =>
- (field instanceof TextField) ? this.createIcon(field.Data) :
- await this.props.Document.GetTAsync(KeyStore.Layout, TextField).then(field =>
- (field instanceof TextField) ? this.createIcon(field.Data) : undefined)));
- }
-
@undoBatch
@action
drop = (e: Event, de: DragManager.DropEvent) => {
@@ -353,6 +250,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
}
}
+ @action
onDrop = (e: React.DragEvent) => {
let text = e.dataTransfer.getData("text/plain");
if (!e.isDefaultPrevented() && text && text.startsWith("<div")) {
@@ -389,12 +287,10 @@ export class DocumentView extends React.Component<DocumentViewProps> {
isSelected = () => SelectionManager.IsSelected(this);
select = (ctrlPressed: boolean) => SelectionManager.SelectDoc(this, ctrlPressed);
-
@computed get nativeWidth() { return this.props.Document.GetNumber(KeyStore.NativeWidth, 0); }
@computed get nativeHeight() { return this.props.Document.GetNumber(KeyStore.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%";
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 5d9aefd61..a16fd5007 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -16,7 +16,7 @@ import { FieldView, FieldViewProps } from './FieldView';
import "./ImageBox.scss";
import React = require("react");
import { InkingControl } from '../InkingControl';
-import { InkTool } from '../../../fields/InkField';
+import { NumberField } from '../../../fields/NumberField';
@observer
export class ImageBox extends React.Component<FieldViewProps> {
@@ -42,7 +42,8 @@ export class ImageBox extends React.Component<FieldViewProps> {
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);
- this.props.Document.SetNumber(KeyStore.Height, this.props.Document.Width() * h / w);
+ this.props.Document.GetTAsync(KeyStore.Width, NumberField, field =>
+ field && this.props.Document.SetNumber(KeyStore.Height, field.Data * h / w));
}
}