aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Utils.ts15
-rw-r--r--src/client/northstar/dash-fields/HistogramField.ts12
-rw-r--r--src/client/views/EditableView.scss1
-rw-r--r--src/client/views/Main.tsx9
-rw-r--r--src/client/views/MainOverlayTextBox.tsx3
-rw-r--r--src/client/views/collections/CollectionBaseView.tsx2
-rw-r--r--src/client/views/collections/CollectionDockingView.tsx3
-rw-r--r--src/client/views/collections/CollectionSchemaView.tsx3
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx104
-rw-r--r--src/client/views/collections/collectionFreeForm/MarqueeView.tsx1
-rw-r--r--src/client/views/nodes/CollectionFreeFormDocumentView.tsx18
-rw-r--r--src/client/views/nodes/DocumentContentsView.tsx33
-rw-r--r--src/client/views/nodes/DocumentView.scss5
-rw-r--r--src/client/views/nodes/DocumentView.tsx5
-rw-r--r--src/client/views/nodes/FieldView.tsx3
-rw-r--r--src/client/views/nodes/FormattedTextBox.tsx3
-rw-r--r--src/client/views/nodes/ImageBox.tsx57
-rw-r--r--src/client/views/nodes/KeyValueBox.tsx6
-rw-r--r--src/client/views/nodes/WebBox.scss6
-rw-r--r--src/client/views/nodes/WebBox.tsx35
20 files changed, 195 insertions, 129 deletions
diff --git a/src/Utils.ts b/src/Utils.ts
index e07d4e82d..dec6245ef 100644
--- a/src/Utils.ts
+++ b/src/Utils.ts
@@ -87,10 +87,25 @@ export class Utils {
}
}
+export function OmitKeys(obj: any, keys: any, addKeyFunc?: (dup: any) => void) {
+ var dup: any = {};
+ for (var key in obj) {
+ if (keys.indexOf(key) === -1) {
+ dup[key] = obj[key];
+ }
+ }
+ addKeyFunc && addKeyFunc(dup);
+ return dup;
+}
+
export function returnTrue() { return true; }
export function returnFalse() { return false; }
+export function returnOne() { return 1; }
+
+export function returnZero() { return 0; }
+
export function emptyFunction() { }
export function emptyDocFunction(doc: Document) { }
diff --git a/src/client/northstar/dash-fields/HistogramField.ts b/src/client/northstar/dash-fields/HistogramField.ts
index 82de51d56..c699691a4 100644
--- a/src/client/northstar/dash-fields/HistogramField.ts
+++ b/src/client/northstar/dash-fields/HistogramField.ts
@@ -6,6 +6,7 @@ import { BasicField } from "../../../fields/BasicField";
import { Field, FieldId } from "../../../fields/Field";
import { CurrentUserUtils } from "../../../server/authentication/models/current_user_utils";
import { Types } from "../../../server/Message";
+import { OmitKeys } from "../../../Utils";
export class HistogramField extends BasicField<HistogramOperation> {
@@ -13,17 +14,8 @@ export class HistogramField extends BasicField<HistogramOperation> {
super(data ? data : HistogramOperation.Empty, save, id);
}
- omitKeys(obj: any, keys: any) {
- var dup: any = {};
- for (var key in obj) {
- if (keys.indexOf(key) === -1) {
- dup[key] = obj[key];
- }
- }
- return dup;
- }
toString(): string {
- return JSON.stringify(this.omitKeys(this.Data, ['Links', 'BrushLinks', 'Result', 'BrushColors', 'FilterModels', 'FilterOperand']));
+ return JSON.stringify(OmitKeys(this.Data, ['Links', 'BrushLinks', 'Result', 'BrushColors', 'FilterModels', 'FilterOperand']));
}
Copy(): Field {
diff --git a/src/client/views/EditableView.scss b/src/client/views/EditableView.scss
index be3c5069a..ea401eaf9 100644
--- a/src/client/views/EditableView.scss
+++ b/src/client/views/EditableView.scss
@@ -2,5 +2,4 @@
overflow-wrap: break-word;
word-wrap: break-word;
hyphens: auto;
- max-width: 300px;
} \ No newline at end of file
diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx
index d26586216..6c18e9ad5 100644
--- a/src/client/views/Main.tsx
+++ b/src/client/views/Main.tsx
@@ -17,7 +17,7 @@ import { CurrentUserUtils } from '../../server/authentication/models/current_use
import { MessageStore } from '../../server/Message';
import { RouteStore } from '../../server/RouteStore';
import { ServerUtils } from '../../server/ServerUtil';
-import { emptyDocFunction, emptyFunction, returnTrue, Utils } from '../../Utils';
+import { emptyDocFunction, emptyFunction, returnTrue, Utils, returnOne } from '../../Utils';
import { Documents } from '../documents/Documents';
import { ColumnAttributeModel } from '../northstar/core/attribute/AttributeModel';
import { AttributeTransformationModel } from '../northstar/core/attribute/AttributeTransformationModel';
@@ -84,7 +84,11 @@ export class Main extends React.Component {
this.initEventListeners();
this.initAuthenticationRouters();
- this.initializeNorthstar();
+ try {
+ this.initializeNorthstar();
+ } catch (e) {
+
+ }
}
componentDidMount() { window.onpopstate = this.onHistory; }
@@ -178,7 +182,6 @@ export class Main extends React.Component {
<DocumentView Document={mainCont}
addDocument={undefined}
removeDocument={undefined}
- opacity={1}
ScreenToLocalTransform={Transform.Identity}
ContentScaling={noScaling}
PanelWidth={pwidthFunc}
diff --git a/src/client/views/MainOverlayTextBox.tsx b/src/client/views/MainOverlayTextBox.tsx
index df1addbc7..6d43d88f0 100644
--- a/src/client/views/MainOverlayTextBox.tsx
+++ b/src/client/views/MainOverlayTextBox.tsx
@@ -56,7 +56,8 @@ export class MainOverlayTextBox extends React.Component<MainOverlayTextBoxProps>
@action
textScroll = (e: React.UIEvent) => {
if (this._textProxyDiv.current && this._textTargetDiv) {
- this._textTargetDiv.scrollTop = this.TextScroll = this._textProxyDiv.current.children[0].scrollTop;
+ this.TextScroll = (e as any)._targetInst.stateNode.scrollTop;// this._textProxyDiv.current.children[0].scrollTop;
+ this._textTargetDiv.scrollTop = this.TextScroll;
}
}
diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx
index bff56e8c3..444f6fc26 100644
--- a/src/client/views/collections/CollectionBaseView.tsx
+++ b/src/client/views/collections/CollectionBaseView.tsx
@@ -88,7 +88,7 @@ export class CollectionBaseView extends React.Component<CollectionViewProps> {
var curPage = props.Document.GetNumber(KeyStore.CurPage, -1);
doc.SetOnPrototype(KeyStore.Page, new NumberField(curPage));
if (this.isAnnotationOverlay) {
- doc.SetOnPrototype(KeyStore.Zoom, new NumberField(this.props.Document.GetNumber(KeyStore.Scale, 1)));
+ doc.SetNumber(KeyStore.Zoom, this.props.Document.GetNumber(KeyStore.Scale, 1));
}
if (curPage >= 0) {
doc.SetOnPrototype(KeyStore.AnnotationOn, props.Document);
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 4f7d4fc0d..2b96e7678 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -8,7 +8,7 @@ import { Document } from "../../../fields/Document";
import { KeyStore } from "../../../fields/KeyStore";
import Measure from "react-measure";
import { FieldId, Opt, Field, FieldWaiting } from "../../../fields/Field";
-import { Utils, returnTrue, emptyFunction, emptyDocFunction } from "../../../Utils";
+import { Utils, returnTrue, emptyFunction, emptyDocFunction, returnOne } from "../../../Utils";
import { Server } from "../../Server";
import { undoBatch } from "../../util/UndoManager";
import { DocumentView } from "../nodes/DocumentView";
@@ -343,7 +343,6 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
<DocumentView key={this._document.Id} Document={this._document}
addDocument={undefined}
removeDocument={undefined}
- opacity={1}
ContentScaling={this._contentScaling}
PanelWidth={this._nativeWidth}
PanelHeight={this._nativeHeight}
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 2c99c9c67..4f4068e7a 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -12,7 +12,7 @@ import { Field, Opt } from "../../../fields/Field";
import { Key } from "../../../fields/Key";
import { KeyStore } from "../../../fields/KeyStore";
import { ListField } from "../../../fields/ListField";
-import { emptyDocFunction, emptyFunction, returnFalse } from "../../../Utils";
+import { emptyDocFunction, emptyFunction, returnFalse, returnOne } from "../../../Utils";
import { Server } from "../../Server";
import { SetupDrag } from "../../util/DragManager";
import { CompileScript, ToField } from "../../util/Scripting";
@@ -308,7 +308,6 @@ export class CollectionSchemaView extends CollectionSubView {
<DocumentView Document={doc}
addDocument={this.props.addDocument} removeDocument={this.props.removeDocument}
isTopMost={false}
- opacity={1}
selectOnLoad={false}
ScreenToLocalTransform={this.getPreviewTransform}
ContentScaling={this.getContentScaling}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index cb4e8fb2e..03426cb27 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -5,7 +5,7 @@ import { Document } from "../../../../fields/Document";
import { FieldWaiting } from "../../../../fields/Field";
import { KeyStore } from "../../../../fields/KeyStore";
import { TextField } from "../../../../fields/TextField";
-import { emptyFunction, returnFalse } from "../../../../Utils";
+import { emptyFunction, returnFalse, returnOne } from "../../../../Utils";
import { DocumentManager } from "../../../util/DocumentManager";
import { DragManager } from "../../../util/DragManager";
import { SelectionManager } from "../../../util/SelectionManager";
@@ -14,7 +14,7 @@ import { undoBatch } from "../../../util/UndoManager";
import { COLLECTION_BORDER_WIDTH } from "../../../views/globalCssVariables.scss";
import { InkingCanvas } from "../../InkingCanvas";
import { Main } from "../../Main";
-import { CollectionFreeFormDocumentView } from "../../nodes/CollectionFreeFormDocumentView";
+import { CollectionFreeFormDocumentView, CollectionFreeFormDocumentViewProps } from "../../nodes/CollectionFreeFormDocumentView";
import { DocumentContentsView } from "../../nodes/DocumentContentsView";
import { DocumentViewProps } from "../../nodes/DocumentView";
import { CollectionSubView, SubCollectionViewProps } from "../CollectionSubView";
@@ -111,7 +111,11 @@ export class CollectionFreeFormView extends CollectionSubView {
@action
onPointerDown = (e: React.PointerEvent): void => {
- if (((e.button === 2 && (!this.isAnnotationOverlay || this.zoomScaling !== 1)) || e.button === 0) && this.props.active()) {
+ let childSelected = this.props.Document.GetList(this.props.fieldKey, [] as Document[]).filter(doc => doc).reduce((childSelected, doc) => {
+ var dv = DocumentManager.Instance.getDocumentView(doc);
+ return childSelected || (dv && SelectionManager.IsSelected(dv) ? true : false);
+ }, false);
+ if (((e.button === 2 && (!this.isAnnotationOverlay || this.zoomScaling !== 1)) || (e.button === 0 && e.altKey)) && (childSelected || this.props.active())) {
document.removeEventListener("pointermove", this.onPointerMove);
document.addEventListener("pointermove", this.onPointerMove);
document.removeEventListener("pointerup", this.onPointerUp);
@@ -130,38 +134,36 @@ export class CollectionFreeFormView extends CollectionSubView {
@action
onPointerMove = (e: PointerEvent): void => {
- if (!e.cancelBubble && this.props.active()) {
- if ((!this.isAnnotationOverlay || this.zoomScaling !== 1) && !e.shiftKey) {
- let x = this.props.Document.GetNumber(KeyStore.PanX, 0);
- let y = this.props.Document.GetNumber(KeyStore.PanY, 0);
- let docs = this.props.Document.GetList(this.props.fieldKey, [] as Document[]);
- let [dx, dy] = this.getTransform().transformDirection(e.clientX - this._lastX, e.clientY - this._lastY);
- if (!this.isAnnotationOverlay) {
- let minx = docs.length ? docs[0].GetNumber(KeyStore.X, 0) : 0;
- let maxx = docs.length ? docs[0].GetNumber(KeyStore.Width, 0) + minx : minx;
- let miny = docs.length ? docs[0].GetNumber(KeyStore.Y, 0) : 0;
- let maxy = docs.length ? docs[0].GetNumber(KeyStore.Height, 0) + miny : miny;
- let ranges = docs.filter(doc => doc).reduce((range, doc) => {
- let x = doc.GetNumber(KeyStore.X, 0);
- let xe = x + doc.GetNumber(KeyStore.Width, 0);
- let y = doc.GetNumber(KeyStore.Y, 0);
- let ye = y + doc.GetNumber(KeyStore.Height, 0);
- return [[range[0][0] > x ? x : range[0][0], range[0][1] < xe ? xe : range[0][1]],
- [range[1][0] > y ? y : range[1][0], range[1][1] < ye ? ye : range[1][1]]];
- }, [[minx, maxx], [miny, maxy]]);
- let panelwidth = this._pwidth / this.scale / 2;
- let panelheight = this._pheight / this.scale / 2;
- if (x - dx < ranges[0][0] - panelwidth) x = ranges[0][1] + panelwidth + dx;
- if (x - dx > ranges[0][1] + panelwidth) x = ranges[0][0] - panelwidth + dx;
- if (y - dy < ranges[1][0] - panelheight) y = ranges[1][1] + panelheight + dy;
- if (y - dy > ranges[1][1] + panelheight) y = ranges[1][0] - panelheight + dy;
- }
- this.SetPan(x - dx, y - dy);
- this._lastX = e.pageX;
- this._lastY = e.pageY;
- e.stopPropagation();
- e.preventDefault();
+ if (!e.cancelBubble) {
+ let x = this.props.Document.GetNumber(KeyStore.PanX, 0);
+ let y = this.props.Document.GetNumber(KeyStore.PanY, 0);
+ let docs = this.props.Document.GetList(this.props.fieldKey, [] as Document[]);
+ let [dx, dy] = this.getTransform().transformDirection(e.clientX - this._lastX, e.clientY - this._lastY);
+ if (!this.isAnnotationOverlay) {
+ let minx = docs.length ? docs[0].GetNumber(KeyStore.X, 0) : 0;
+ let maxx = docs.length ? docs[0].GetNumber(KeyStore.Width, 0) + minx : minx;
+ let miny = docs.length ? docs[0].GetNumber(KeyStore.Y, 0) : 0;
+ let maxy = docs.length ? docs[0].GetNumber(KeyStore.Height, 0) + miny : miny;
+ let ranges = docs.filter(doc => doc).reduce((range, doc) => {
+ let x = doc.GetNumber(KeyStore.X, 0);
+ let xe = x + doc.GetNumber(KeyStore.Width, 0);
+ let y = doc.GetNumber(KeyStore.Y, 0);
+ let ye = y + doc.GetNumber(KeyStore.Height, 0);
+ return [[range[0][0] > x ? x : range[0][0], range[0][1] < xe ? xe : range[0][1]],
+ [range[1][0] > y ? y : range[1][0], range[1][1] < ye ? ye : range[1][1]]];
+ }, [[minx, maxx], [miny, maxy]]);
+ let panelwidth = this._pwidth / this.scale / 2;
+ let panelheight = this._pheight / this.scale / 2;
+ if (x - dx < ranges[0][0] - panelwidth) x = ranges[0][1] + panelwidth + dx;
+ if (x - dx > ranges[0][1] + panelwidth) x = ranges[0][0] - panelwidth + dx;
+ if (y - dy < ranges[1][0] - panelheight) y = ranges[1][1] + panelheight + dy;
+ if (y - dy > ranges[1][1] + panelheight) y = ranges[1][0] - panelheight + dy;
}
+ this.SetPan(x - dx, y - dy);
+ this._lastX = e.pageX;
+ this._lastY = e.pageY;
+ e.stopPropagation();
+ e.preventDefault();
}
}
@@ -170,6 +172,13 @@ export class CollectionFreeFormView extends CollectionSubView {
// if (!this.props.active()) {
// return;
// }
+ let childSelected = this.props.Document.GetList(this.props.fieldKey, [] as Document[]).filter(doc => doc).reduce((childSelected, doc) => {
+ var dv = DocumentManager.Instance.getDocumentView(doc);
+ return childSelected || (dv && SelectionManager.IsSelected(dv) ? true : false);
+ }, false);
+ if (!this.props.isSelected() && !childSelected && !this.props.isTopMost) {
+ return;
+ }
e.stopPropagation();
let coefficient = 1000;
@@ -200,7 +209,6 @@ export class CollectionFreeFormView extends CollectionSubView {
this.props.Document.SetNumber(KeyStore.Scale, localTransform.Scale);
this.SetPan(-localTransform.TranslateX / localTransform.Scale, -localTransform.TranslateY / localTransform.Scale);
e.stopPropagation();
- e.preventDefault();
}
}
@@ -261,10 +269,9 @@ export class CollectionFreeFormView extends CollectionSubView {
this.props.focus(this.props.Document);
}
- getDocumentViewProps(document: Document, opacity: number): DocumentViewProps {
+ getDocumentViewProps(document: Document): DocumentViewProps {
return {
Document: document,
- opacity: opacity,
addDocument: this.props.addDocument,
removeDocument: this.props.removeDocument,
moveDocument: this.props.moveDocument,
@@ -283,14 +290,25 @@ export class CollectionFreeFormView extends CollectionSubView {
@computed
get views() {
+ let pw = this.props.CollectionView.props
var curPage = this.props.Document.GetNumber(KeyStore.CurPage, -1);
let docviews = this.props.Document.GetList(this.props.fieldKey, [] as Document[]).filter(doc => doc).reduce((prev, doc) => {
var page = doc.GetNumber(KeyStore.Page, -1);
var zoom = doc.GetNumber(KeyStore.Zoom, 1);
- var dv = DocumentManager.Instance.getDocumentView(doc);
- let opacity = this.isAnnotationOverlay && (!dv || !SelectionManager.IsSelected(dv)) ? 1 - Math.abs(zoom - this.scale) : 1;
- if ((page === curPage || page === -1)) {
- prev.push(<CollectionFreeFormDocumentView key={doc.Id} {...this.getDocumentViewProps(doc, opacity)} />);
+ let zoomFade = 1;
+ var documentView = DocumentManager.Instance.getDocumentView(doc);
+ if (documentView) {
+ let transform = (documentView.props.ScreenToLocalTransform().scale(documentView.props.ContentScaling())).inverse();
+ var [sptX, sptY] = transform.transformPoint(0, 0);
+ let [bptX, bptY] = transform.transformPoint(documentView.props.PanelWidth(), documentView.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;
+ }
+ if (page === curPage || page === -1) {
+ prev.push(<CollectionFreeFormDocumentView key={doc.Id} {...this.getDocumentViewProps(doc)} zoomFade={zoomFade} />);
}
return prev;
}, [] as JSX.Element[]);
@@ -305,13 +323,13 @@ export class CollectionFreeFormView extends CollectionSubView {
@computed
get backgroundView() {
return !this.backgroundLayout ? (null) :
- (<DocumentContentsView {...this.getDocumentViewProps(this.props.Document, 1)}
+ (<DocumentContentsView {...this.getDocumentViewProps(this.props.Document)}
layoutKey={KeyStore.BackgroundLayout} isTopMost={this.props.isTopMost} isSelected={returnFalse} select={emptyFunction} />);
}
@computed
get overlayView() {
return !this.overlayLayout ? (null) :
- (<DocumentContentsView {...this.getDocumentViewProps(this.props.Document, 1)}
+ (<DocumentContentsView {...this.getDocumentViewProps(this.props.Document)}
layoutKey={KeyStore.OverlayLayout} isTopMost={this.props.isTopMost} isSelected={returnFalse} select={emptyFunction} />);
}
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index dbab790d4..783470286 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -160,7 +160,6 @@ export class MarqueeView extends React.Component<MarqueeViewProps>
pany: 0,
width: bounds.width,
height: bounds.height,
- backgroundColor: "Transparent",
ink: inkData ? this.marqueeInkSelect(inkData) : undefined,
title: "a nested collection"
});
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 0aa152209..b00cefbf6 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -1,4 +1,4 @@
-import { computed } from "mobx";
+import { computed, trace } from "mobx";
import { observer } from "mobx-react";
import { KeyStore } from "../../../fields/KeyStore";
import { NumberField } from "../../../fields/NumberField";
@@ -6,13 +6,17 @@ import { Transform } from "../../util/Transform";
import { DocumentView, DocumentViewProps } from "./DocumentView";
import "./DocumentView.scss";
import React = require("react");
+import { OmitKeys } from "../../../Utils";
+export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps {
+ zoomFade: number;
+}
@observer
-export class CollectionFreeFormDocumentView extends React.Component<DocumentViewProps> {
+export class CollectionFreeFormDocumentView extends React.Component<CollectionFreeFormDocumentViewProps> {
private _mainCont = React.createRef<HTMLDivElement>();
- constructor(props: DocumentViewProps) {
+ constructor(props: CollectionFreeFormDocumentViewProps) {
super(props);
}
@@ -55,20 +59,24 @@ export class CollectionFreeFormDocumentView extends React.Component<DocumentView
@computed
get docView() {
- return <DocumentView {...this.props}
+ return <DocumentView {...this.docViewProps}
ContentScaling={this.contentScaling}
ScreenToLocalTransform={this.getTransform}
PanelWidth={this.panelWidth}
PanelHeight={this.panelHeight}
/>;
}
+ @computed
+ get docViewProps(): DocumentViewProps {
+ return (OmitKeys(this.props, ['zoomFade']));
+ }
panelWidth = () => this.props.Document.GetBoolean(KeyStore.Minimized, false) ? 10 : this.props.PanelWidth();
panelHeight = () => this.props.Document.GetBoolean(KeyStore.Minimized, false) ? 10 : this.props.PanelHeight();
render() {
return (
<div className="collectionFreeFormDocumentView-container" ref={this._mainCont} style={{
- opacity: this.props.opacity,
+ opacity: this.props.zoomFade,
transformOrigin: "left top",
transform: this.transform,
pointerEvents: "all",
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index 88900c4b1..76f852601 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -23,7 +23,7 @@ import { HistogramBox } from "../../northstar/dash-nodes/HistogramBox";
import React = require("react");
import { Document } from "../../../fields/Document";
import { FieldViewProps } from "./FieldView";
-import { Without } from "../../../Utils";
+import { Without, OmitKeys } from "../../../Utils";
const JsxParser = require('react-jsx-parser').default; //TODO Why does this need to be imported like this?
type BindingProps = Without<FieldViewProps, 'fieldKey'>;
@@ -44,35 +44,8 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & {
CreateBindings(): JsxBindings {
- let {
- Document,
- isSelected,
- select,
- isTopMost,
- selectOnLoad,
- ScreenToLocalTransform,
- ContainingCollectionView,
- addDocument,
- removeDocument,
- onActiveChanged,
- parentActive: active,
- } = this.props;
- let bindings: JsxBindings = {
- props: {
- Document,
- isSelected,
- select,
- isTopMost,
- selectOnLoad,
- ScreenToLocalTransform,
- ContainingCollectionView,
- active,
- onActiveChanged,
- addDocument,
- removeDocument,
- focus,
- }
- };
+ let bindings: JsxBindings = { props: OmitKeys(this.props, ['parentActive'], (obj: any) => obj.active = this.props.parentActive) };
+
for (const key of this.layoutKeys) {
bindings[key.Name + "Key"] = key; // this maps string values of the form <keyname>Key to an actual key Kestore.keyname e.g, "DataKey" => KeyStore.Data
}
diff --git a/src/client/views/nodes/DocumentView.scss b/src/client/views/nodes/DocumentView.scss
index a946ac1a8..5071c9440 100644
--- a/src/client/views/nodes/DocumentView.scss
+++ b/src/client/views/nodes/DocumentView.scss
@@ -1,6 +1,6 @@
@import "../globalCssVariables";
-.documentView-node {
+.documentView-node .documentView-node-topMost {
position: inherit;
top: 0;
left:0;
@@ -28,6 +28,9 @@
height: calc(100% - 20px);
}
}
+.documentView-node-topMost {
+ background: white;
+}
.minimized-box {
height: 10px;
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index e74b609bb..e77102fff 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -28,7 +28,6 @@ import React = require("react");
export interface DocumentViewProps {
ContainingCollectionView: Opt<CollectionView | CollectionPDFView | CollectionVideoView>;
Document: Document;
- opacity: number;
addDocument?: (doc: Document, allowDuplicates?: boolean) => boolean;
removeDocument?: (doc: Document) => boolean;
moveDocument?: (doc: Document, targetCollection: Document, addDocument: (document: Document) => boolean) => boolean;
@@ -216,7 +215,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
}
}
fullScreenClicked = (e: React.MouseEvent): void => {
- CollectionDockingView.Instance.OpenFullScreen(this.props.Document);
+ CollectionDockingView.Instance.OpenFullScreen((this.props.Document.GetPrototype() as Document).MakeDelegate());
ContextMenu.Instance.clearItems();
ContextMenu.Instance.addItem({
description: "Close Full Screen",
@@ -429,7 +428,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
);
return (
<div
- className="documentView-node"
+ className={`documentView-node${this.props.isTopMost ? "-topmost" : ""}`}
ref={this._mainCont}
style={{
background: backgroundcolor,
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index 562de4827..ebd25f937 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -19,7 +19,7 @@ import { ListField } from "../../../fields/ListField";
import { DocumentContentsView } from "./DocumentContentsView";
import { Transform } from "../../util/Transform";
import { KeyStore } from "../../../fields/KeyStore";
-import { returnFalse, emptyDocFunction } from "../../../Utils";
+import { returnFalse, emptyDocFunction, emptyFunction, returnOne } from "../../../Utils";
import { CollectionView } from "../collections/CollectionView";
import { CollectionPDFView } from "../collections/CollectionPDFView";
import { CollectionVideoView } from "../collections/CollectionVideoView";
@@ -83,7 +83,6 @@ export class FieldView extends React.Component<FieldViewProps> {
<DocumentContentsView Document={field}
addDocument={undefined}
removeDocument={undefined}
- opacity={1}
ScreenToLocalTransform={Transform.Identity}
ContentScaling={() => 1}
PanelWidth={() => 100}
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index 87c1bcb1e..8963484b6 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -1,4 +1,4 @@
-import { action, IReactionDisposer, reaction } from "mobx";
+import { action, IReactionDisposer, reaction, trace, computed } from "mobx";
import { baseKeymap } from "prosemirror-commands";
import { history, redo, undo } from "prosemirror-history";
import { keymap } from "prosemirror-keymap";
@@ -17,6 +17,7 @@ import React = require("react");
import { TextField } from "../../../fields/TextField";
import { KeyStore } from "../../../fields/KeyStore";
import { MainOverlayTextBox } from "../MainOverlayTextBox";
+import { observer } from "mobx-react";
const { buildMenuItems } = require("prosemirror-example-setup");
const { menuBar } = require("prosemirror-menu");
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 6b0a3a799..9bdbfbb5d 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -11,23 +11,27 @@ import { FieldView, FieldViewProps } from './FieldView';
import "./ImageBox.scss";
import React = require("react");
import { Utils } from '../../../Utils';
+import { ListField } from '../../../fields/ListField';
+import { DragManager } from '../../util/DragManager';
+import { undoBatch } from '../../util/UndoManager';
+import { TextField } from '../../../fields/TextField';
+import { Document } from '../../../fields/Document';
@observer
export class ImageBox extends React.Component<FieldViewProps> {
public static LayoutString() { return FieldView.LayoutString(ImageBox); }
- private _ref: React.RefObject<HTMLDivElement>;
private _imgRef: React.RefObject<HTMLImageElement>;
private _downX: number = 0;
private _downY: number = 0;
private _lastTap: number = 0;
@observable private _photoIndex: number = 0;
@observable private _isOpen: boolean = false;
+ private dropDisposer?: DragManager.DragDropDisposer;
constructor(props: FieldViewProps) {
super(props);
- this._ref = React.createRef();
this._imgRef = React.createRef();
this.state = {
photoIndex: 0,
@@ -45,9 +49,43 @@ export class ImageBox extends React.Component<FieldViewProps> {
componentDidMount() {
}
+ protected createDropTarget = (ele: HTMLDivElement) => {
+ if (this.dropDisposer) {
+ this.dropDisposer();
+ }
+ if (ele) {
+ this.dropDisposer = DragManager.MakeDropTarget(ele, { handlers: { drop: this.drop.bind(this) } });
+ }
+ }
+
componentWillUnmount() {
}
+
+ @undoBatch
+ drop = (e: Event, de: DragManager.DropEvent) => {
+ if (de.data instanceof DragManager.DocumentDragData) {
+ de.data.droppedDocuments.map(action((drop: Document) => {
+ let layout = drop.GetText(KeyStore.BackgroundLayout, "");
+ 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]));
+ }
+ let imgList = this.props.Document.GetList(KeyStore.Data, [] as any[]);
+ if (imgList) {
+ let field = drop.Get(KeyStore.Data);
+ if (field === FieldWaiting) { }
+ else if (field instanceof ImageField) imgList.push(field);
+ else if (field instanceof ListField) imgList.push(field.Data);
+ }
+ e.stopPropagation();
+ }
+ }))
+ // de.data.removeDocument() bcz: need to implement
+ }
+ }
+
onPointerDown = (e: React.PointerEvent): void => {
if (Date.now() - this._lastTap < 300) {
if (e.buttons === 1) {
@@ -70,8 +108,7 @@ export class ImageBox extends React.Component<FieldViewProps> {
e.stopPropagation();
}
- lightbox = (path: string) => {
- const images = [path];
+ lightbox = (images: string[]) => {
if (this._isOpen) {
return (<Lightbox
mainSrc={images[this._photoIndex]}
@@ -104,13 +141,15 @@ export class ImageBox extends React.Component<FieldViewProps> {
render() {
let field = this.props.Document.Get(this.props.fieldKey);
- let path = field === FieldWaiting ? "https://image.flaticon.com/icons/svg/66/66163.svg" :
- field instanceof ImageField ? field.Data.href : "http://www.cs.brown.edu/~bcz/face.gif";
+ let paths: string[] = ["http://www.cs.brown.edu/~bcz/face.gif"];
+ if (field === FieldWaiting) paths = ["https://image.flaticon.com/icons/svg/66/66163.svg"];
+ else if (field instanceof ImageField) paths = [field.Data.href];
+ else if (field instanceof ListField) paths = field.Data.filter(val => val as ImageField).map(p => (p as ImageField).Data.href);
let nativeWidth = this.props.Document.GetNumber(KeyStore.NativeWidth, 1);
return (
- <div className="imageBox-cont" onPointerDown={this.onPointerDown} ref={this._ref} onContextMenu={this.specificContextMenu}>
- <img src={path} width={nativeWidth} alt="Image not found" ref={this._imgRef} onLoad={this.onLoad} />
- {this.lightbox(path)}
+ <div className="imageBox-cont" onPointerDown={this.onPointerDown} ref={this.createDropTarget} onContextMenu={this.specificContextMenu}>
+ <img src={paths[0]} width={nativeWidth} alt="Image not found" ref={this._imgRef} onLoad={this.onLoad} />
+ {this.lightbox(paths)}
</div>);
}
} \ No newline at end of file
diff --git a/src/client/views/nodes/KeyValueBox.tsx b/src/client/views/nodes/KeyValueBox.tsx
index 29e4af160..ddbec014b 100644
--- a/src/client/views/nodes/KeyValueBox.tsx
+++ b/src/client/views/nodes/KeyValueBox.tsx
@@ -26,12 +26,6 @@ export class KeyValueBox extends React.Component<FieldViewProps> {
super(props);
}
-
-
- shouldComponentUpdate() {
- return false;
- }
-
@action
onEnterKey = (e: React.KeyboardEvent): void => {
if (e.key === 'Enter') {
diff --git a/src/client/views/nodes/WebBox.scss b/src/client/views/nodes/WebBox.scss
index c73bc0c47..2ad1129a4 100644
--- a/src/client/views/nodes/WebBox.scss
+++ b/src/client/views/nodes/WebBox.scss
@@ -9,6 +9,12 @@
overflow: scroll;
}
+#webBox-htmlSpan {
+ position: absolute;
+ top:0;
+ left:0;
+}
+
.webBox-button {
padding : 0vw;
border: none;
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index 90ce72c41..1edb4d826 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -18,21 +18,40 @@ export class WebBox extends React.Component<FieldViewProps> {
@computed get html(): string { return this.props.Document.GetHtml(KeyStore.Data, ""); }
+ _ignore = 0;
+ onPreWheel = (e: React.WheelEvent) => {
+ this._ignore = e.timeStamp;
+ }
+ onPrePointer = (e: React.PointerEvent) => {
+ this._ignore = e.timeStamp;
+ }
+ onPostPointer = (e: React.PointerEvent) => {
+ if (this._ignore !== e.timeStamp) {
+ e.stopPropagation();
+ }
+ }
+ onPostWheel = (e: React.WheelEvent) => {
+ if (this._ignore !== e.timeStamp) {
+ e.stopPropagation();
+ }
+ }
render() {
let field = this.props.Document.Get(this.props.fieldKey);
let path = field === FieldWaiting ? "https://image.flaticon.com/icons/svg/66/66163.svg" :
field instanceof WebField ? field.Data.href : "https://crossorigin.me/" + "https://cs.brown.edu";
- let content = this.html ?
- <span dangerouslySetInnerHTML={{ __html: this.html }}></span> :
- <div style={{ width: "100%", height: "100%", position: "absolute" }}>
- <iframe src={path} style={{ position: "absolute", width: "100%", height: "100%" }}></iframe>
- {this.props.isSelected() ? (null) : <div style={{ width: "100%", height: "100%", position: "absolute" }} />}
+ let content =
+ <div style={{ width: "100%", height: "100%", position: "absolute" }} onWheel={this.onPostWheel} onPointerDown={this.onPostPointer} onPointerMove={this.onPostPointer} onPointerUp={this.onPostPointer}>
+ {this.html ? <span id="webBox-htmlSpan" dangerouslySetInnerHTML={{ __html: this.html }} /> :
+ <iframe src={path} style={{ position: "absolute", width: "100%", height: "100%" }} />}
</div>;
return (
- <div className="webBox-cont" >
- {content}
- </div>);
+ <>
+ <div className="webBox-cont" >
+ {content}
+ </div>
+ {this.props.isSelected() ? (null) : <div onWheel={this.onPreWheel} onPointerDown={this.onPrePointer} onPointerMove={this.onPrePointer} onPointerUp={this.onPrePointer} style={{ width: "100%", height: "100%", position: "absolute" }} />}
+ </>);
}
} \ No newline at end of file