aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/views/OverlayView.tsx9
-rw-r--r--src/client/views/ScriptBox.scss17
-rw-r--r--src/client/views/ScriptBox.tsx10
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx69
4 files changed, 72 insertions, 33 deletions
diff --git a/src/client/views/OverlayView.tsx b/src/client/views/OverlayView.tsx
index 72f1068ce..f8fc94274 100644
--- a/src/client/views/OverlayView.tsx
+++ b/src/client/views/OverlayView.tsx
@@ -1,6 +1,7 @@
import * as React from "react";
import { observer } from "mobx-react";
import { observable, action } from "mobx";
+import { Utils } from "../../Utils";
export type OverlayDisposer = () => void;
@@ -15,7 +16,7 @@ export type OverlayElementOptions = {
export class OverlayView extends React.Component {
public static Instance: OverlayView;
@observable.shallow
- private _elements: { ele: JSX.Element, options: OverlayElementOptions }[] = [];
+ private _elements: { ele: JSX.Element, id: string, options: OverlayElementOptions }[] = [];
constructor(props: any) {
super(props);
@@ -26,7 +27,7 @@ export class OverlayView extends React.Component {
@action
addElement(ele: JSX.Element, options: OverlayElementOptions): OverlayDisposer {
- const eleWithPosition = { ele, options };
+ const eleWithPosition = { ele, options, id: Utils.GenerateGuid() };
this._elements.push(eleWithPosition);
return action(() => {
const index = this._elements.indexOf(eleWithPosition);
@@ -37,8 +38,8 @@ export class OverlayView extends React.Component {
render() {
return (
<div>
- {this._elements.map(({ ele, options: { x, y, width, height } }) => (
- <div style={{ position: "absolute", transform: `translate(${x}px, ${y}px)`, width, height }}>{ele}</div>
+ {this._elements.map(({ ele, options: { x, y, width, height }, id }) => (
+ <div key={id} style={{ position: "absolute", transform: `translate(${x}px, ${y}px)`, width, height }}>{ele}</div>
))}
</div>
);
diff --git a/src/client/views/ScriptBox.scss b/src/client/views/ScriptBox.scss
new file mode 100644
index 000000000..28326624a
--- /dev/null
+++ b/src/client/views/ScriptBox.scss
@@ -0,0 +1,17 @@
+.scriptBox-outerDiv {
+ width: 100%;
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+}
+
+.scriptBox-toolbar {
+ width: 100%;
+}
+
+.scriptBox-textArea {
+ width: 100%;
+ height: 100%;
+ box-sizing: border-box;
+ resize: none;
+} \ No newline at end of file
diff --git a/src/client/views/ScriptBox.tsx b/src/client/views/ScriptBox.tsx
index aea9d52a4..fa236c2da 100644
--- a/src/client/views/ScriptBox.tsx
+++ b/src/client/views/ScriptBox.tsx
@@ -2,15 +2,23 @@ import * as React from "react";
import { observer } from "mobx-react";
import { observable, action } from "mobx";
+import "./ScriptBox.scss";
+
export interface ScriptBoxProps {
onSave: (text: string, onError: (error: string) => void) => void;
onCancel?: () => void;
+ initialText?: string;
}
@observer
export class ScriptBox extends React.Component<ScriptBoxProps> {
@observable
- private _scriptText: string = "";
+ private _scriptText: string;
+
+ constructor(props: ScriptBoxProps) {
+ super(props);
+ this._scriptText = props.initialText || "";
+ }
@action
onChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 23c0fdd0d..edd2fb1b0 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -28,7 +28,7 @@ import { MarqueeView } from "./MarqueeView";
import React = require("react");
import v5 = require("uuid/v5");
import { ScriptField } from "../../../../new_fields/ScriptField";
-import { OverlayView } from "../../OverlayView";
+import { OverlayView, OverlayElementOptions } from "../../OverlayView";
import { ScriptBox } from "../../ScriptBox";
import { CompileScript } from "../../../util/Scripting";
@@ -36,7 +36,9 @@ import { CompileScript } from "../../../util/Scripting";
export const panZoomSchema = createSchema({
panX: "number",
panY: "number",
- scale: "number"
+ scale: "number",
+ arrangeScript: ScriptField,
+ arrangeInit: ScriptField,
});
type PanZoomDocument = makeInterface<[typeof panZoomSchema, typeof positionSchema, typeof pageSchema]>;
@@ -392,28 +394,34 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
};
}
- getCalculatedPositions(doc: Doc, index: number, collection: Doc): { x?: number, y?: number, width?: number, height?: number } | undefined {
- const script = Cast(this.props.Document.arrangeScript, ScriptField);
- if (!script) {
- return undefined;
- }
- const result = script.script.run({ doc, index, collection });
+ getCalculatedPositions(doc: Doc, index: number, collection: Doc, script: ScriptField, state: any): { x?: number, y?: number, width?: number, height?: number, state?: any } {
+ const result = script.script.run({ doc, index, collection, state });
if (!result.success) {
- return undefined;
+ return {};
}
- return result.result;
+ return result.result === undefined ? {} : result.result;
}
@computed.struct
get views() {
let curPage = FieldValue(this.Document.curPage, -1);
+ const initScript = this.Document.arrangeInit;
+ const script = this.Document.arrangeScript;
+ let state: any = undefined;
+ if (initScript) {
+ const initResult = initScript.script.run();
+ if (initResult.success) {
+ state = initResult.result;
+ }
+ }
let docviews = this.childDocs.reduce((prev, doc) => {
if (!(doc instanceof Doc)) return prev;
var page = NumCast(doc.page, -1);
if (Math.round(page) === Math.round(curPage) || page === -1) {
let minim = BoolCast(doc.isMinimized, false);
if (minim === undefined || !minim) {
- const pos = this.getCalculatedPositions(doc, prev.length, this.Document) || {};
+ const pos = script ? this.getCalculatedPositions(doc, prev.length, this.Document, script, state) : {};
+ state = pos.state === undefined ? state : pos.state;
prev.push(<CollectionFreeFormDocumentView key={doc[Id]} x={pos.x} y={pos.y} width={pos.width} height={pos.height} {...this.getChildDocumentViewProps(doc)} />);
}
}
@@ -458,23 +466,28 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
ContextMenu.Instance.addItem({
description: "Add freeform arrangement",
event: () => {
- let overlayDisposer: () => void;
- let scriptingBox = <ScriptBox onCancel={() => overlayDisposer()} onSave={(text, onError) => {
- const script = CompileScript(text, {
- params: {
- doc: "Doc", index: "number", collection: "Doc"
- },
- requiredType: "{x: number, y: number, width?: number, height?: number}",
- typecheck: false
- });
- if (!script.compiled) {
- onError(script.errors.map(error => error.messageText).join("\n"));
- return;
- }
- this.props.Document.arrangeScript = new ScriptField(script);
- overlayDisposer();
- }} />;
- overlayDisposer = OverlayView.Instance.addElement(scriptingBox, { x: 100, y: 100, width: 200, height: 200 });
+ let addOverlay = (key: "arrangeScript" | "arrangeInit", options: OverlayElementOptions, params?: Record<string, string>, requiredType?: string) => {
+ let overlayDisposer: () => void;
+ const script = this.Document[key];
+ let originalText: string | undefined = undefined;
+ if (script) originalText = script.script.originalScript;
+ let scriptingBox = <ScriptBox initialText={originalText} onCancel={() => overlayDisposer()} onSave={(text, onError) => {
+ const script = CompileScript(text, {
+ params,
+ requiredType,
+ typecheck: false
+ });
+ if (!script.compiled) {
+ onError(script.errors.map(error => error.messageText).join("\n"));
+ return;
+ }
+ this.Document[key] = new ScriptField(script);
+ overlayDisposer();
+ }} />;
+ overlayDisposer = OverlayView.Instance.addElement(scriptingBox, options);
+ };
+ addOverlay("arrangeInit", { x: 400, y: 100, width: 400, height: 300 }, undefined, undefined);
+ addOverlay("arrangeScript", { x: 400, y: 500, width: 400, height: 300 }, { doc: "Doc", index: "number", collection: "Doc", state:"any" }, "{x: number, y: number, width?: number, height?: number}");
}
});
}