aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/nodes/CollectionFreeFormDocumentView.tsx')
-rw-r--r--src/client/views/nodes/CollectionFreeFormDocumentView.tsx166
1 files changed, 64 insertions, 102 deletions
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 2ba0458f5..499b83c0f 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -1,23 +1,24 @@
-import { computed, trace, action, reaction, IReactionDisposer } from "mobx";
+import { computed, IReactionDisposer, reaction, action } from "mobx";
import { observer } from "mobx-react";
+import { Doc } from "../../../new_fields/Doc";
+import { List } from "../../../new_fields/List";
+import { createSchema, listSpec, makeInterface } from "../../../new_fields/Schema";
+import { BoolCast, Cast, FieldValue, NumCast } from "../../../new_fields/Types";
+import { OmitKeys } from "../../../Utils";
import { Transform } from "../../util/Transform";
+import { DocComponent } from "../DocComponent";
import { DocumentView, DocumentViewProps, positionSchema } from "./DocumentView";
import "./DocumentView.scss";
import React = require("react");
-import { DocComponent } from "../DocComponent";
-import { createSchema, makeInterface, listSpec } from "../../../new_fields/Schema";
-import { FieldValue, Cast, NumCast, BoolCast } from "../../../new_fields/Types";
-import { OmitKeys, Utils } from "../../../Utils";
+import { UndoManager } from "../../util/UndoManager";
import { SelectionManager } from "../../util/SelectionManager";
-import { Doc } from "../../../new_fields/Doc";
-import { List } from "../../../new_fields/List";
export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps {
}
const schema = createSchema({
zoomBasis: "number",
- zIndex: "number"
+ zIndex: "number",
});
//TODO Types: The import order is wrong, so positionSchema is undefined
@@ -27,8 +28,6 @@ const FreeformDocument = makeInterface(schema, positionSchema);
@observer
export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeFormDocumentViewProps, FreeformDocument>(FreeformDocument) {
private _mainCont = React.createRef<HTMLDivElement>();
- private _downX: number = 0;
- private _downY: number = 0;
_bringToFrontDisposer?: IReactionDisposer;
@computed get transform() {
@@ -40,9 +39,8 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
@computed get zoom(): number { return 1 / FieldValue(this.Document.zoomBasis, 1); }
@computed get nativeWidth(): number { return FieldValue(this.Document.nativeWidth, 0); }
@computed get nativeHeight(): number { return FieldValue(this.Document.nativeHeight, 0); }
- @computed get width(): number { return FieldValue(this.Document.width, 0); }
- @computed get height(): number { return FieldValue(this.Document.height, 0); }
- @computed get zIndex(): number { return FieldValue(this.Document.zIndex, 0); }
+ @computed get width(): number { return BoolCast(this.props.Document.willMaximize) ? 0 : FieldValue(this.Document.width, 0); }
+ @computed get height(): number { return BoolCast(this.props.Document.willMaximize) ? 0 : FieldValue(this.Document.height, 0); }
set width(w: number) {
this.Document.width = w;
@@ -56,14 +54,9 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
this.Document.width = this.nativeWidth / this.nativeHeight * h;
}
}
- set zIndex(h: number) {
- this.Document.zIndex = h;
- }
-
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)
@@ -71,11 +64,11 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
@computed
get docView() {
return <DocumentView {...OmitKeys(this.props, ['zoomFade']).omit}
- toggleMinimized={this.toggleMinimized}
ContentScaling={this.contentScaling}
ScreenToLocalTransform={this.getTransform}
PanelWidth={this.panelWidth}
PanelHeight={this.panelHeight}
+ collapseToPoint={this.collapseToPoint}
/>;
}
@@ -84,99 +77,74 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
this.props.bringToFront(this.props.Document);
if (values instanceof List) {
let scrpt = this.props.ScreenToLocalTransform().transformPoint(values[0], values[1]);
- this.animateBetweenIcon(true, scrpt, [values[2], values[3]], values[4], values[5], values[6], this.props.Document, values[7] ? true : false);
+ this.animateBetweenIcon(true, scrpt, [this.Document.x || 0, this.Document.y || 0],
+ this.Document.width || 0, this.Document.height || 0, values[2], values[3] ? true : false);
}
- });
+ }, { fireImmediately: true });
}
componentWillUnmount() {
if (this._bringToFrontDisposer) this._bringToFrontDisposer();
}
- animateBetweenIcon(first: boolean, icon: number[], targ: number[], width: number, height: number, stime: number, target: Doc, maximizing: boolean) {
+ static _undoBatch?: UndoManager.Batch = undefined;
+ @action
+ public collapseToPoint = async (scrpt: number[], expandedDocs: Doc[] | undefined): Promise<void> => {
+ SelectionManager.DeselectAll();
+ if (expandedDocs) {
+ if (!CollectionFreeFormDocumentView._undoBatch) {
+ CollectionFreeFormDocumentView._undoBatch = UndoManager.StartBatch("iconAnimating");
+ }
+ let isMinimized: boolean | undefined;
+ expandedDocs.map(d => Doc.GetProto(d)).map(maximizedDoc => {
+ let iconAnimating = Cast(maximizedDoc.isIconAnimating, List);
+ if (!iconAnimating || (Date.now() - iconAnimating[2] > 1000)) {
+ if (isMinimized === undefined) {
+ isMinimized = BoolCast(maximizedDoc.isMinimized, false);
+ }
+ maximizedDoc.willMaximize = isMinimized;
+ maximizedDoc.isMinimized = false;
+ maximizedDoc.isIconAnimating = new List<number>([scrpt[0], scrpt[1], Date.now(), isMinimized ? 1 : 0]);
+ }
+ });
+ setTimeout(() => {
+ CollectionFreeFormDocumentView._undoBatch && CollectionFreeFormDocumentView._undoBatch.end();
+ CollectionFreeFormDocumentView._undoBatch = undefined;
+ }, 500);
+ }
+ }
+
+ animateBetweenIcon(first: boolean, icon: number[], targ: number[], width: number, height: number, stime: number, 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.width = maximizing ? 25 + (width - 25) * progress : width + (25 - width) * progress;
- target.height = maximizing ? 25 + (height - 25) * progress : height + (25 - height) * progress;
- target.x = pval[0];
- target.y = pval[1];
+ this.props.Document.width = maximizing ? 25 + (width - 25) * progress : width + (25 - width) * progress;
+ this.props.Document.height = maximizing ? 25 + (height - 25) * progress : height + (25 - height) * progress;
+ this.props.Document.x = pval[0];
+ this.props.Document.y = pval[1];
+ if (first) {
+ this.props.Document.proto!.willMaximize = false;
+ }
if (now < stime + 200) {
- this.animateBetweenIcon(false, icon, targ, width, height, stime, target, maximizing);
+ this.animateBetweenIcon(false, icon, targ, width, height, stime, maximizing);
}
else {
if (!maximizing) {
- target.isMinimized = true;
- target.x = targ[0];
- target.y = targ[1];
- target.width = width;
- target.height = height;
+ this.props.Document.proto!.isMinimized = true;
+ this.props.Document.x = targ[0];
+ this.props.Document.y = targ[1];
+ this.props.Document.width = width;
+ this.props.Document.height = height;
}
- target.isIconAnimating = undefined;
+ this.props.Document.proto!.isIconAnimating = undefined;
}
},
2);
}
- @action
- public toggleIcon = async (): Promise<void> => {
- SelectionManager.DeselectAll();
- let isMinimized: boolean | undefined;
- let maximizedDocs = await Cast(this.props.Document.maximizedDocs, listSpec(Doc));
- let minimizedDoc: Doc | undefined = this.props.Document;
- if (!maximizedDocs) {
- minimizedDoc = await Cast(this.props.Document.minimizedDoc, Doc);
- if (minimizedDoc) maximizedDocs = await Cast(minimizedDoc.maximizedDocs, listSpec(Doc));
- }
- if (minimizedDoc && maximizedDocs && maximizedDocs instanceof List) {
- let minimizedTarget = minimizedDoc;
- maximizedDocs.map(maximizedDoc => {
- let iconAnimating = Cast(maximizedDoc.isIconAnimating, List);
- if (!iconAnimating || (Date.now() - iconAnimating[6] > 1000)) {
- if (isMinimized === undefined) {
- isMinimized = BoolCast(maximizedDoc.isMinimized, false);
- }
- let minx = NumCast(minimizedTarget.x, undefined) + NumCast(minimizedTarget.width, undefined) / 2;
- let miny = NumCast(minimizedTarget.y, undefined) + NumCast(minimizedTarget.height, undefined) / 2;
- let maxx = NumCast(maximizedDoc.x, undefined);
- let maxy = NumCast(maximizedDoc.y, undefined);
- let maxw = NumCast(maximizedDoc.width, undefined);
- let maxh = NumCast(maximizedDoc.height, undefined);
- if (minx !== undefined && miny !== undefined && maxx !== undefined && maxy !== undefined &&
- maxw !== undefined && maxh !== undefined) {
- let scrpt = this.props.ScreenToLocalTransform().inverse().transformPoint(minx, miny);
- maximizedDoc.isMinimized = false;
- maximizedDoc.isIconAnimating = new List<number>([scrpt[0], scrpt[1], maxx, maxy, maxw, maxh, Date.now(), isMinimized ? 1 : 0])
- }
- }
- });
- }
- }
- onPointerDown = (e: React.PointerEvent): void => {
- this._downX = e.clientX;
- this._downY = e.clientY;
- e.stopPropagation();
- }
- onClick = async (e: React.MouseEvent) => {
- e.stopPropagation();
- let ctrlKey = e.ctrlKey;
- if (Math.abs(e.clientX - this._downX) < Utils.DRAG_THRESHOLD &&
- Math.abs(e.clientY - this._downY) < Utils.DRAG_THRESHOLD) {
- if (await BoolCast(this.props.Document.isButton, false)) {
- let maximizedDocs = await Cast(this.props.Document.maximizedDocs, listSpec(Doc));
- if (maximizedDocs) { // bcz: need a better way to associate behaviors with click events on widget-documents
- if (ctrlKey)
- this.props.addDocument && maximizedDocs.filter(d => d instanceof Doc).map(maxDoc => this.props.addDocument!(maxDoc, false));
- this.toggleIcon();
- }
- }
- }
- }
-
- onPointerEnter = (e: React.PointerEvent): void => { this.props.Document.libraryBrush = true; }
- onPointerLeave = (e: React.PointerEvent): void => { this.props.Document.libraryBrush = false; }
borderRounding = () => {
let br = NumCast(this.props.Document.borderRounding);
@@ -190,25 +158,19 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
let maximizedDoc = FieldValue(Cast(this.props.Document.maximizedDocs, listSpec(Doc)));
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;
+ // 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 = Math.min(50 * NumCast(this.props.Document.nativeWidth, 0), 1800);
let fadeUp = .75 * screenWidth;
let fadeDown = (maximizedDoc ? .0075 : .075) * screenWidth;
- zoomFade = w < fadeDown /* || w > fadeUp */ ? Math.max(0.1, Math.min(1, 2 - (w < fadeDown ? fadeDown / w : w / fadeUp))) : 1;
+ // zoomFade = w < fadeDown /* || w > fadeUp */ ? Math.max(0.1, Math.min(1, 2 - (w < fadeDown ? Math.sqrt(Math.sqrt(fadeDown / w)) : w / fadeUp))) : 1;
return (
<div className="collectionFreeFormDocumentView-container" ref={this._mainCont}
- onPointerDown={this.onPointerDown}
- onPointerEnter={this.onPointerEnter} onPointerLeave={this.onPointerLeave}
- onClick={this.onClick}
style={{
- outlineColor: "black",
- outlineStyle: "dashed",
- outlineWidth: BoolCast(this.props.Document.libraryBrush, false) ? `${0.5 / this.contentScaling()}px` : "0px",
opacity: zoomFade,
borderRadius: `${this.borderRounding()}px`,
transformOrigin: "left top",
@@ -217,7 +179,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
width: this.width,
height: this.height,
position: "absolute",
- zIndex: this.zIndex,
+ zIndex: this.Document.zIndex || 0,
backgroundColor: "transparent"
}} >
{this.docView}