aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Wilkins <samwilkins333@gmail.com>2020-01-31 11:05:03 -0500
committerSam Wilkins <samwilkins333@gmail.com>2020-01-31 11:05:03 -0500
commit5ad15ac012262ac15e152b995cbcb042c5b7cf89 (patch)
treefcd3404add281aff240aeb4c9546d0ba16b7d8ec
parent96de4bf18d5721d2b7957d7adb8ad3393462c4d1 (diff)
parentb0544ea44ef78a93deb9290815f95d6d9308447d (diff)
Merge branch 'master' of https://github.com/browngraphicslab/Dash-Web
-rw-r--r--src/client/documents/Documents.ts4
-rw-r--r--src/client/util/DocumentManager.ts2
-rw-r--r--src/client/util/DropConverter.ts5
-rw-r--r--src/client/util/InteractionUtils.tsx5
-rw-r--r--src/client/util/RichTextRules.ts2
-rw-r--r--src/client/util/RichTextSchema.tsx14
-rw-r--r--src/client/views/ContextMenu.tsx4
-rw-r--r--src/client/views/DocumentDecorations.tsx2
-rw-r--r--src/client/views/EditableView.tsx19
-rw-r--r--src/client/views/TemplateMenu.tsx12
-rw-r--r--src/client/views/collections/CollectionDockingView.tsx2
-rw-r--r--src/client/views/collections/CollectionPivotView.tsx51
-rw-r--r--src/client/views/collections/CollectionStackingViewFieldColumn.tsx2
-rw-r--r--src/client/views/collections/CollectionSubView.tsx2
-rw-r--r--src/client/views/collections/CollectionTreeView.tsx1
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx38
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx21
-rw-r--r--src/client/views/collections/collectionFreeForm/MarqueeView.tsx11
-rw-r--r--src/client/views/nodes/DocumentView.tsx31
-rw-r--r--src/client/views/nodes/FormattedTextBox.tsx16
-rw-r--r--src/client/views/nodes/PresBox.scss4
-rw-r--r--src/client/views/nodes/PresBox.tsx6
-rw-r--r--src/client/views/presentationview/PresElementBox.scss24
-rw-r--r--src/new_fields/Doc.ts2
-rw-r--r--src/pen-gestures/ndollar.ts7
-rw-r--r--src/server/authentication/models/current_user_utils.ts5
26 files changed, 189 insertions, 103 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index fa5707288..49c03a96f 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -75,7 +75,7 @@ export interface DocumentOptions {
_yMargin?: number; // gap between top edge of dcoument and start of masonry/stacking layouts
_textTemplate?: RichTextField; // template used by a formattedTextBox to create a text box to render
_itemIndex?: number; // which item index the carousel viewer is showing
- _hideSidebar?: boolean; //whether an annotationsidebar should be displayed for text docuemnts
+ _showSidebar?: boolean; //whether an annotationsidebar should be displayed for text docuemnts
x?: number;
y?: number;
z?: number;
@@ -340,7 +340,7 @@ export namespace Docs {
export namespace Create {
const delegateKeys = ["x", "y", "layoutKey", "_width", "_height", "_panX", "_panY", "_viewType", "_nativeWidth", "_nativeHeight", "_dropAction", "_annotationOn",
- "_chromeStatus", "_forceActive", "_autoHeight", "_fitWidth", "_LODdisable", "_itemIndex", "_hideSidebar"];
+ "_chromeStatus", "_forceActive", "_autoHeight", "_fitWidth", "_LODdisable", "_itemIndex", "_showSidebar"];
/**
* This function receives the relevant document prototype and uses
diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts
index fb4c2155a..f024b9116 100644
--- a/src/client/util/DocumentManager.ts
+++ b/src/client/util/DocumentManager.ts
@@ -140,7 +140,7 @@ export class DocumentManager {
if (first) annotatedDoc = first.props.Document;
}
if (docView) { // we have a docView already and aren't forced to create a new one ... just focus on the document. TODO move into view if necessary otherwise just highlight?
- docView.props.focus(docView.props.Document, false);
+ docView.props.focus(docView.props.Document, willZoom);
highlight();
} else {
const contextDocs = docContext ? await DocListCastAsync(docContext.data) : undefined;
diff --git a/src/client/util/DropConverter.ts b/src/client/util/DropConverter.ts
index 669ac5336..d0f1d86cb 100644
--- a/src/client/util/DropConverter.ts
+++ b/src/client/util/DropConverter.ts
@@ -35,10 +35,11 @@ export function convertDropDataToButtons(data: DragManager.DocumentDragData) {
if (!doc.onDragStart && !doc.onClick && !doc.isButtonBar) {
const layoutDoc = doc.layout instanceof Doc && doc.layout.isTemplateForField ? doc.layout : doc;
if (layoutDoc.type === DocumentType.COL || layoutDoc.type === DocumentType.TEXT || layoutDoc.type === DocumentType.IMG) {
- layoutDoc.isTemplateDoc = makeTemplate(layoutDoc);
+ makeTemplate(layoutDoc);
} else {
- layoutDoc.isTemplateDoc = (layoutDoc.layout instanceof Doc) && !data.userDropAction;
+ (layoutDoc.layout instanceof Doc) && !data.userDropAction;
}
+ layoutDoc.isTemplateDoc = true;
dbox = Docs.Create.FontIconDocument({ _nativeWidth: 100, _nativeHeight: 100, _width: 100, _height: 100, backgroundColor: StrCast(doc.backgroundColor), title: "Custom", icon: layoutDoc.isTemplateDoc ? "font" : "bolt" });
dbox.dragFactory = layoutDoc;
dbox.removeDropProperties = doc.removeDropProperties instanceof ObjectField ? ObjectField.MakeCopy(doc.removeDropProperties) : undefined;
diff --git a/src/client/util/InteractionUtils.tsx b/src/client/util/InteractionUtils.tsx
index 1fe95474c..7194feb2e 100644
--- a/src/client/util/InteractionUtils.tsx
+++ b/src/client/util/InteractionUtils.tsx
@@ -63,7 +63,7 @@ export namespace InteractionUtils {
export function GetMyTargetTouches(mte: InteractionUtils.MultiTouchEvent<React.TouchEvent | TouchEvent>, prevPoints: Map<number, React.Touch>, ignorePen: boolean): React.Touch[] {
const myTouches = new Array<React.Touch>();
for (const pt of mte.touches) {
- if (!ignorePen || (pt.radiusX > 1 && pt.radiusY > 1)) {
+ if (!ignorePen || ((pt as any).radiusX > 1 && (pt as any).radiusY > 1)) {
for (const tPt of mte.targetTouches) {
if (tPt?.screenX === pt?.screenX && tPt?.screenY === pt?.screenY) {
if (pt && prevPoints.has(pt.identifier)) {
@@ -73,6 +73,9 @@ export namespace InteractionUtils {
}
}
}
+ // if (mte.touches.length !== myTouches.length) {
+ // throw Error("opo")
+ // }
return myTouches;
}
diff --git a/src/client/util/RichTextRules.ts b/src/client/util/RichTextRules.ts
index 00ce3ef73..8411cc6ee 100644
--- a/src/client/util/RichTextRules.ts
+++ b/src/client/util/RichTextRules.ts
@@ -101,7 +101,7 @@ export const inpRules = {
}
});
const node = (state.doc.resolve(start) as any).nodeAfter;
- const dashDoc = schema.nodes.dashDoc.create({ width: 75, height: 75, title: "dashDoc", docid: docId, float: "right", fieldKey: match[2], alias: Utils.GenerateGuid() });
+ const dashDoc = schema.nodes.dashDoc.create({ width: 75, height: 75, title: "dashDoc", docid: docId, float: "right", fieldKey: match[2]?.substring(1), alias: Utils.GenerateGuid() });
const sm = state.storedMarks || undefined;
return node ? state.tr.replaceRangeWith(start, end, dashDoc).setStoredMarks([...node.marks, ...(sm ? sm : [])]) : state.tr;
}),
diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx
index d1e0f07cb..9e4f06919 100644
--- a/src/client/util/RichTextSchema.tsx
+++ b/src/client/util/RichTextSchema.tsx
@@ -21,6 +21,7 @@ import { FormattedTextBox } from "../views/nodes/FormattedTextBox";
import { ObjectField } from "../../new_fields/ObjectField";
import { ComputedField } from "../../new_fields/ScriptField";
import { observer } from "mobx-react";
+import { Id } from "../../new_fields/FieldSymbols";
const blockquoteDOM: DOMOutputSpecArray = ["blockquote", 0], hrDOM: DOMOutputSpecArray = ["hr"],
preDOM: DOMOutputSpecArray = ["pre", ["code", 0]], brDOM: DOMOutputSpecArray = ["br"], ulDOM: DOMOutputSpecArray = ["ul", 0];
@@ -759,11 +760,15 @@ export class DashDocView {
return true;
};
const alias = node.attrs.alias;
- DocServer.GetRefField(node.attrs.docid + alias).then(async dashDoc => {
+
+ const docid = node.attrs.docid || tbox.props.DataDoc?.[Id] || tbox.dataDoc?.[Id];
+ DocServer.GetRefField(docid + alias).then(async dashDoc => {
if (!(dashDoc instanceof Doc)) {
- alias && DocServer.GetRefField(node.attrs.docid).then(async dashDocBase => {
+ alias && DocServer.GetRefField(docid).then(async dashDocBase => {
if (dashDocBase instanceof Doc) {
- self.doRender(Doc.MakeAlias(dashDocBase), removeDoc, node, view, getPos);
+ const aliasedDoc = Doc.MakeDelegate(dashDocBase, docid + alias);
+ aliasedDoc.layoutKey = "layout_" + node.attrs.fieldKey;
+ self.doRender(aliasedDoc, removeDoc, node, view, getPos);
}
});
} else {
@@ -785,7 +790,6 @@ export class DashDocView {
}
doRender(dashDoc: Doc, removeDoc: any, node: any, view: any, getPos: any) {
this._dashDoc = dashDoc;
- dashDoc._hideSidebar = true;
if (node.attrs.width !== dashDoc._width + "px" || node.attrs.height !== dashDoc._height + "px") {
try { // bcz: an exception will be thrown if two aliases are open at the same time when a doc view comment is made
view.dispatch(view.state.tr.setNodeMarkup(getPos(), null, { ...node.attrs, width: dashDoc._width + "px", height: dashDoc._height + "px" }));
@@ -812,7 +816,7 @@ export class DashDocView {
}, { fireImmediately: true });
ReactDOM.render(<DocumentView
Document={finalLayout}
- DataDoc={Doc.AreProtosEqual(this._textBox.Document, dashDoc) ? this._textBox.dataDoc : undefined}
+ DataDoc={!node.attrs.docid ? this._textBox.dataDoc : undefined}
LibraryPath={this._textBox.props.LibraryPath}
fitToBox={BoolCast(dashDoc._fitToBox)}
addDocument={returnFalse}
diff --git a/src/client/views/ContextMenu.tsx b/src/client/views/ContextMenu.tsx
index ac803d977..4d04d4e89 100644
--- a/src/client/views/ContextMenu.tsx
+++ b/src/client/views/ContextMenu.tsx
@@ -134,13 +134,13 @@ export class ContextMenu extends React.Component {
}
@action
- displayMenu = (x: number, y: number) => {
+ displayMenu = (x: number, y: number, initSearch = "") => {
//maxX and maxY will change if the UI/font size changes, but will work for any amount
//of items added to the menu
this._pageX = x;
this._pageY = y;
- this._searchString = "";
+ this._searchString = initSearch;
this._shouldDisplay = true;
}
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 7c4391ec0..c5034b901 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -265,7 +265,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
const layoutKey = Cast(dv.props.Document.layoutKey, "string", null);
const collapse = layoutKey !== "layout_icon";
if (collapse) {
- if (layoutKey) dv.props.Document.deiconifyLayout = layoutKey.replace("layout_", "");
+ if (layoutKey && layoutKey !== "layout") dv.props.Document.deiconifyLayout = layoutKey.replace("layout_", "");
dv.setCustomView(collapse, "icon");
} else {
const deiconifyLayout = Cast(dv.props.Document.deiconifyLayout, "string", null);
diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx
index 780c5b2f4..84c6b0dfd 100644
--- a/src/client/views/EditableView.tsx
+++ b/src/client/views/EditableView.tsx
@@ -46,6 +46,7 @@ export interface EditableProps {
onClick?: (e: React.MouseEvent) => boolean;
isEditingCallback?: (isEditing: boolean) => void;
menuCallback?: (x: number, y: number) => void;
+ showMenuOnLoad?: boolean;
HeadingObject?: SchemaHeaderField | undefined;
HeadingsHack?: number;
toggle?: () => void;
@@ -77,6 +78,8 @@ export class EditableView extends React.Component<EditableProps> {
}
}
+ _didShow = false;
+
@action
onKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === "Tab") {
@@ -97,16 +100,20 @@ export class EditableView extends React.Component<EditableProps> {
this._editing = false;
this.props.isEditingCallback?.(false);
} else if (e.key === ":") {
- this.props.menuCallback?.(e.currentTarget.offsetLeft, e.currentTarget.offsetTop);
+ this.props.menuCallback?.(e.currentTarget.getBoundingClientRect().x, e.currentTarget.getBoundingClientRect().y);
}
}
@action
onClick = (e: React.MouseEvent) => {
e.nativeEvent.stopPropagation();
- if (!this.props.onClick || !this.props.onClick(e)) {
- this._editing = true;
- this.props.isEditingCallback?.(true);
+ if (this._ref.current && this.props.showMenuOnLoad) {
+ this.props.menuCallback?.(this._ref.current.getBoundingClientRect().x, this._ref.current.getBoundingClientRect().y);
+ } else {
+ if (!this.props.onClick || !this.props.onClick(e)) {
+ this._editing = true;
+ this.props.isEditingCallback?.(true);
+ }
}
e.stopPropagation();
}
@@ -130,6 +137,7 @@ export class EditableView extends React.Component<EditableProps> {
return wasFocused !== this._editing;
}
+ _ref = React.createRef<HTMLDivElement>();
render() {
if (this._editing && this.props.GetValue() !== undefined) {
return this.props.autosuggestProps
@@ -156,9 +164,10 @@ export class EditableView extends React.Component<EditableProps> {
style={{ display: this.props.display, fontSize: this.props.fontSize }}
/>;
} else {
- if (this.props.autosuggestProps) this.props.autosuggestProps.resetValue();
+ this.props.autosuggestProps?.resetValue();
return (this.props.contents instanceof ObjectField ? (null) :
<div className={`editableView-container-editing${this.props.oneLine ? "-oneLine" : ""}`}
+ ref={this._ref}
style={{ display: this.props.display, minHeight: "20px", height: `${this.props.height ? this.props.height : "auto"}`, maxHeight: `${this.props.maxHeight}` }}
onClick={this.onClick}>
<span style={{ fontStyle: this.props.fontStyle, fontSize: this.props.fontSize }}>{this.props.contents}</span>
diff --git a/src/client/views/TemplateMenu.tsx b/src/client/views/TemplateMenu.tsx
index d5554fd4f..f61eb9cd0 100644
--- a/src/client/views/TemplateMenu.tsx
+++ b/src/client/views/TemplateMenu.tsx
@@ -90,22 +90,22 @@ export class TemplateMenu extends React.Component<TemplateMenuProps> {
// todo: add brushes to brushMap to save with a style name
onCustomKeypress = (e: React.KeyboardEvent) => {
if (e.key === "Enter") {
- runInAction(() => TemplateMenu._addedKeys.add(this._customRef.current!.value));
+ runInAction(() => this._addedKeys.add(this._customRef.current!.value));
}
}
componentDidMount() {
- !TemplateMenu._addedKeys && (TemplateMenu._addedKeys = new ObservableSet(["narrative"]));
+ !this._addedKeys && (this._addedKeys = new ObservableSet());
Array.from(Object.keys(Doc.GetProto(this.props.docViews[0].props.Document))).
filter(key => key.startsWith("layout_")).
- map(key => runInAction(() => TemplateMenu._addedKeys.add(key.replace("layout_", ""))));
+ map(key => runInAction(() => this._addedKeys.add(key.replace("layout_", ""))));
DocListCast(Cast(CurrentUserUtils.UserDocument.expandingButtons, Doc, null)?.data)?.map(btnDoc => {
if (StrCast(Cast(btnDoc?.dragFactory, Doc, null)?.title)) {
- runInAction(() => TemplateMenu._addedKeys.add(StrCast(Cast(btnDoc?.dragFactory, Doc, null)?.title)));
+ runInAction(() => this._addedKeys.add(StrCast(Cast(btnDoc?.dragFactory, Doc, null)?.title)));
}
});
}
- static _addedKeys = new ObservableSet(["narrative"]);
+ _addedKeys = new ObservableSet();
_customRef = React.createRef<HTMLInputElement>();
render() {
const layout = Doc.Layout(this.props.docViews[0].Document);
@@ -114,7 +114,7 @@ export class TemplateMenu extends React.Component<TemplateMenuProps> {
templateMenu.push(<TemplateToggle key={template.Name} template={template} checked={checked} toggle={this.toggleTemplate} />));
templateMenu.push(<OtherToggle key={"float"} name={"Float"} checked={this.props.docViews[0].Document.z ? true : false} toggle={this.toggleFloat} />);
templateMenu.push(<OtherToggle key={"chrome"} name={"Chrome"} checked={layout._chromeStatus !== "disabled"} toggle={this.toggleChrome} />);
- TemplateMenu._addedKeys && Array.from(TemplateMenu._addedKeys).map(layout =>
+ this._addedKeys && Array.from(this._addedKeys).map(layout =>
templateMenu.push(<OtherToggle key={layout} name={layout} checked={StrCast(this.props.docViews[0].Document.layoutKey, "layout") === "layout_" + layout} toggle={e => this.toggleLayout(e, layout)} />)
);
return <ul className="template-list" style={{ display: "block" }}>
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 82cb3bc88..159a1cded 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -643,7 +643,7 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
//add this new doc to props.Document
const curPres = Cast(CurrentUserUtils.UserDocument.curPresentation, Doc) as Doc;
if (curPres) {
- const pinDoc = Docs.Create.PresElementBoxDocument({ backgroundColor: "transparent" });
+ const pinDoc = Docs.Create.PresElementBoxDocument({ backgroundColor: "transparent", _xMargin: 5 });
Doc.GetProto(pinDoc).presentationTargetDoc = doc;
Doc.GetProto(pinDoc).title = ComputedField.MakeFunction('(this.presentationTargetDoc instanceof Doc) && this.presentationTargetDoc.title?.toString()');
const data = Cast(curPres.data, listSpec(Doc));
diff --git a/src/client/views/collections/CollectionPivotView.tsx b/src/client/views/collections/CollectionPivotView.tsx
index 440b6856b..1a84a34a0 100644
--- a/src/client/views/collections/CollectionPivotView.tsx
+++ b/src/client/views/collections/CollectionPivotView.tsx
@@ -16,6 +16,10 @@ import "./CollectionPivotView.scss";
import { CollectionSubView } from "./CollectionSubView";
import { CollectionTreeView } from "./CollectionTreeView";
import React = require("react");
+import { ContextMenu } from "../ContextMenu";
+import { ContextMenuProps } from "../ContextMenuItem";
+import { RichTextField } from "../../../new_fields/RichTextField";
+import { ImageField } from "../../../new_fields/URLField";
@observer
export class CollectionPivotView extends CollectionSubView(doc => doc) {
@@ -36,7 +40,7 @@ export class CollectionPivotView extends CollectionSubView(doc => doc) {
}
}
bodyPanelWidth = () => this.props.PanelWidth() - this._facetWidth;
- getTransform = () => this.props.ScreenToLocalTransform().translate(-200, 0);
+ getTransform = () => this.props.ScreenToLocalTransform().translate(-this._facetWidth, 0);
@computed get _allFacets() {
const facets = new Set<string>();
@@ -98,6 +102,25 @@ export class CollectionPivotView extends CollectionSubView(doc => doc) {
document.removeEventListener("pointerup", this.onPointerUp);
}
+ menuCallback = (x: number, y: number) => {
+ ContextMenu.Instance.clearItems();
+ const docItems: ContextMenuProps[] = [];
+ const keySet: Set<string> = new Set();
+
+ this.childLayoutPairs.map(pair =>
+ Array.from(Object.keys(Doc.GetProto(pair.layout))).filter(fieldKey => pair.layout[fieldKey] instanceof RichTextField || typeof (pair.layout[fieldKey]) === "string").map(fieldKey =>
+ keySet.add(fieldKey)));
+ keySet.toArray().map(fieldKey =>
+ docItems.push({ description: ":" + fieldKey, event: () => this.props.Document.pivotField = fieldKey, icon: "compress-arrows-alt" }));
+ docItems.push({ description: ":(null)", event: () => this.props.Document.pivotField = undefined, icon: "compress-arrows-alt" })
+ ContextMenu.Instance.addItem({ description: "Pivot Fields ...", subitems: docItems, icon: "eye" });
+ const pt = this.props.ScreenToLocalTransform().inverse().transformPoint(x, y);
+ ContextMenu.Instance.displayMenu(x, y, ":");
+ }
+
+ @observable private collapsed: boolean = false;
+ private toggleVisibility = action(() => this.collapsed = !this.collapsed);
+
render() {
const facetCollection = Cast(this.props.Document?._facetCollection, Doc, null);
const flyout = (
@@ -109,20 +132,24 @@ export class CollectionPivotView extends CollectionSubView(doc => doc) {
</label>)}
</div>
);
+ const newEditableViewProps = {
+ GetValue: () => "",
+ SetValue: (value: any) => {
+ if (value?.length) {
+ this.props.Document.pivotField = value;
+ return true;
+ }
+ return false;
+ },
+ showMenuOnLoad: true,
+ contents: ":" + StrCast(this.props.Document.pivotField),
+ toggle: this.toggleVisibility,
+ color: "#f1efeb" // this.props.headingObject ? this.props.headingObject.color : "#f1efeb";
+ };
return !facetCollection ? (null) :
<div className="collectionPivotView" style={{ height: `calc(100% - ${this.props.Document._chromeStatus === "enabled" ? 51 : 0}px)` }}>
<div className={"pivotKeyEntry"}>
- <EditableView
- contents={this.props.Document.pivotField}
- GetValue={() => StrCast(this.props.Document.pivotField)}
- SetValue={value => {
- if (value && value.length) {
- this.props.Document.pivotField = value;
- return true;
- }
- return false;
- }}
- />
+ <EditableView {...newEditableViewProps} menuCallback={this.menuCallback} />
</div>
<div className="collectionPivotView-dragger" key="dragger" onPointerDown={this.onPointerDown} style={{ transform: `translate(${this._facetWidth}px, 0px)` }} >
<span title="library View Dragger" style={{ width: "5px", position: "absolute", top: "0" }} />
diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
index 2a9f903bb..d00ddde6a 100644
--- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
+++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
@@ -312,7 +312,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
}
});
const pt = this.props.screenToLocalTransform().inverse().transformPoint(x, y);
- ContextMenu.Instance.displayMenu(pt[0], pt[1]);
+ ContextMenu.Instance.displayMenu(x, y);
}
render() {
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 8679c8bd1..9482435a0 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -98,7 +98,7 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
get childLayoutPairs(): { layout: Doc; data: Doc; }[] {
const { Document, DataDoc } = this.props;
- const validPairs = this.childDocs.map(doc => Doc.GetLayoutDataDocPair(Document, DataDoc, doc)).filter(pair => pair.layout);
+ const validPairs = this.childDocs.map(doc => Doc.GetLayoutDataDocPair(Document, !this.props.annotationsKey ? DataDoc : undefined, doc)).filter(pair => pair.layout);
return validPairs.map(({ data, layout }) => ({ data: data!, layout: layout! })); // this mapping is a bit of a hack to coerce types
}
get childDocList() {
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 803454113..3cb24f079 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -636,7 +636,6 @@ export class CollectionTreeView extends CollectionSubView(Document) {
if (caption instanceof ObjectField) {
Doc.GetProto(img).caption = ObjectField.MakeCopy(caption);
}
- img._hideSidebar = true;
d.captions = undefined;
});
});
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
index be1317b25..18ca71c2a 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
@@ -4,7 +4,7 @@ import { ScriptBox } from "../../ScriptBox";
import { CompileScript } from "../../../util/Scripting";
import { ScriptField } from "../../../../new_fields/ScriptField";
import { OverlayView, OverlayElementOptions } from "../../OverlayView";
-import { emptyFunction } from "../../../../Utils";
+import { emptyFunction, aggregateBounds } from "../../../../Utils";
import React = require("react");
import { ObservableMap, runInAction } from "mobx";
import { Id, ToString } from "../../../../new_fields/FieldSymbols";
@@ -42,7 +42,13 @@ function toLabel(target: FieldResult<Field>) {
return String(target);
}
-export function computePivotLayout(poolData: ObservableMap<string, any>, pivotDoc: Doc, childDocs: Doc[], childPairs: { layout: Doc, data?: Doc }[], panelDim: number[], viewDefsToJSX: (views: any) => ViewDefResult[]) {
+export function computePivotLayout(
+ poolData: ObservableMap<string, any>,
+ pivotDoc: Doc,
+ pwidth: number, pheight: number,
+ childDocs: Doc[],
+ childPairs: { layout: Doc, data?: Doc }[], panelDim: number[], viewDefsToJSX: (views: any) => ViewDefResult[]
+) {
const pivotAxisWidth = NumCast(pivotDoc.pivotWidth, 200);
const pivotColumnGroups = new Map<FieldResult<Field>, Doc[]>();
@@ -99,21 +105,37 @@ export function computePivotLayout(poolData: ObservableMap<string, any>, pivotDo
x += pivotAxisWidth * (numCols * expander + gap);
});
+ const grpEles = groupNames.map(gn => { return { x: gn.x, y: gn.y, width: gn.width, height: gn.height }; });
+ const docEles = childPairs.map(pair => {
+ const newPos = docMap.get(pair.layout) || { x: NumCast(pair.layout.x), y: NumCast(pair.layout.y) }; // new pos is computed pos, or pos written to the document's fields
+ return {
+ x: newPos.x,
+ y: newPos.y,
+ width: NumCast(pair.layout._width),
+ height: NumCast(pair.layout._height)
+ };
+ }
+ );
+ const aggBounds = aggregateBounds(docEles.concat(grpEles), 0, 0);
+
+ const scale = Math.min(pheight / (aggBounds.b - aggBounds.y), pwidth / (aggBounds.r - aggBounds.x));
+
childPairs.map(pair => {
- const defaultPosition = {
+ const fallbackPos = {
x: NumCast(pair.layout.x),
y: NumCast(pair.layout.y),
z: NumCast(pair.layout.z),
width: NumCast(pair.layout._width),
height: NumCast(pair.layout._height)
};
- const pos = docMap.get(pair.layout) || defaultPosition;
- const data = poolData.get(pair.layout[Id]);
- if (!data || pos.x !== data.x || pos.y !== data.y || pos.z !== data.z || pos.width !== data.width || pos.height !== data.height) {
- runInAction(() => poolData.set(pair.layout[Id], { transition: "transform 1s", ...pos }));
+ const newPosRaw = docMap.get(pair.layout) || fallbackPos; // new pos is computed pos, or pos written to the document's fields
+ const newPos = { x: newPosRaw.x * scale, y: newPosRaw.y * scale, z: newPosRaw.z, width: newPosRaw.width * scale, height: newPosRaw.height * scale };
+ const lastPos = poolData.get(pair.layout[Id]); // last computed pos
+ if (!lastPos || newPos.x !== lastPos.x || newPos.y !== lastPos.y || newPos.z !== lastPos.z || newPos.width !== lastPos.width || newPos.height !== lastPos.height) {
+ runInAction(() => poolData.set(pair.layout[Id], { transition: "transform 1s", ...newPos }));
}
});
- return { elements: viewDefsToJSX(groupNames) };
+ return { elements: viewDefsToJSX(groupNames.map(gname => { return { type: gname.type, text: gname.text, x: gname.x * scale, y: gname.y * scale, width: gname.width * scale, height: gname.height, fontSize: gname.fontSize } })) };
}
export function AddCustomFreeFormLayout(doc: Doc, dataKey: string): () => void {
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 20d20f1f6..90bed2899 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -371,6 +371,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
this._lastX = pt.pageX;
this._lastY = pt.pageY;
e.preventDefault();
+ e.stopPropagation();
}
else {
e.preventDefault();
@@ -386,7 +387,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
case GestureUtils.Gestures.Stroke:
const points = ge.points;
const B = this.getTransform().transformBounds(ge.bounds.left, ge.bounds.top, ge.bounds.width, ge.bounds.height);
- const inkDoc = Docs.Create.InkDocument(InkingControl.Instance.selectedColor, InkingControl.Instance.selectedTool, parseInt(InkingControl.Instance.selectedWidth), points, { x: B.x, y: B.y, _width: B.width, _height: B.height });
+ const inkDoc = Docs.Create.InkDocument(InkingControl.Instance.selectedColor, InkingControl.Instance.selectedTool, parseInt(InkingControl.Instance.selectedWidth), points, { title: "ink stroke", x: B.x, y: B.y, _width: B.width, _height: B.height });
this.addDocument(inkDoc);
e.stopPropagation();
break;
@@ -408,7 +409,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
}
return pass;
});
- this.addDocument(Docs.Create.FreeformDocument(sel, { x: bounds.x, y: bounds.y, _width: bWidth, _height: bHeight, _panX: 0, _panY: 0 }));
+ this.addDocument(Docs.Create.FreeformDocument(sel, { title: "nested collection", x: bounds.x, y: bounds.y, _width: bWidth, _height: bHeight, _panX: 0, _panY: 0 }));
sel.forEach(d => this.props.removeDocument(d));
break;
@@ -775,7 +776,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
}.bind(this));
doPivotLayout(poolData: ObservableMap<string, any>) {
- return computePivotLayout(poolData, this.props.Document, this.childDocs,
+ return computePivotLayout(poolData, this.props.Document, this.props.PanelWidth(), this.props.PanelHeight(), this.childDocs,
this.childLayoutPairs.filter(pair => this.isCurrent(pair.layout)), [this.props.PanelWidth(), this.props.PanelHeight()], this.viewDefsToJSX);
}
@@ -833,23 +834,23 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
layoutDocsInGrid = () => {
UndoManager.RunInBatch(() => {
- const docs = DocListCast(this.Document[this.props.fieldKey]);
+ const docs = this.childLayoutPairs;
const startX = this.Document._panX || 0;
let x = startX;
let y = this.Document._panY || 0;
let i = 0;
- const width = Math.max(...docs.map(doc => NumCast(doc._width)));
- const height = Math.max(...docs.map(doc => NumCast(doc._height)));
- for (const doc of docs) {
- doc.x = x;
- doc.y = y;
+ const width = Math.max(...docs.map(doc => NumCast(doc.layout._width)));
+ const height = Math.max(...docs.map(doc => NumCast(doc.layout._height)));
+ docs.forEach(pair => {
+ pair.layout.x = x;
+ pair.layout.y = y;
x += width + 20;
if (++i === 6) {
i = 0;
x = startX;
y += height + 20;
}
- }
+ });
}, "arrange contents");
}
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index 6a1590b8e..ef2fc2ad1 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -299,7 +299,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
this.hideMarquee();
}
- getCollection = (selected: Doc[]) => {
+ getCollection = (selected: Doc[], asTemplate: boolean) => {
const bounds = this.Bounds;
const defaultPalette = ["rgb(114,229,239)", "rgb(255,246,209)", "rgb(255,188,156)", "rgb(247,220,96)", "rgb(122,176,238)",
"rgb(209,150,226)", "rgb(127,235,144)", "rgb(252,188,189)", "rgb(247,175,81)",];
@@ -321,7 +321,8 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
const usedSequnce = Array.from(usedPaletted.keys()).sort((a, b) => usedPaletted.get(a)! < usedPaletted.get(b)! ? -1 : usedPaletted.get(a)! > usedPaletted.get(b)! ? 1 : 0);
const chosenColor = (usedPaletted.size === 0) ? "white" : palette.length ? palette[0] : usedSequnce[0];
// const inkData = this.ink ? this.ink.inkData : undefined;
- const newCollection = Docs.Create.FreeformDocument(selected, {
+ const creator = asTemplate ? Docs.Create.StackingDocument : Docs.Create.FreeformDocument;
+ const newCollection = creator(selected, {
x: bounds.left,
y: bounds.top,
_panX: 0,
@@ -353,7 +354,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
return d;
});
}
- const newCollection = this.getCollection(selected);
+ const newCollection = this.getCollection(selected, e.key === "t");
this.props.addDocument(newCollection);
this.props.selectDocuments([newCollection], []);
MarqueeOptionsMenu.Instance.fadeOut(true);
@@ -406,12 +407,12 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
this.delete();
e.stopPropagation();
}
- if (e.key === "c" || e.key === "s" || e.key === "S") {
+ if (e.key === "c" || e.key === "t" || e.key === "s" || e.key === "S") {
this._commandExecuted = true;
e.stopPropagation();
e.preventDefault();
(e as any).propagationIsStopped = true;
- if (e.key === "c") {
+ if (e.key === "c" || e.key === "t") {
this.collection(e);
}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 264311a7a..82382c536 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -314,22 +314,25 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
handle1PointerDown = (e: React.TouchEvent, me: InteractionUtils.MultiTouchEvent<React.TouchEvent>) => {
if (this.Document.onPointerDown) return;
- if (!e.nativeEvent.cancelBubble) {
- const touch = InteractionUtils.GetMyTargetTouches(me, this.prevPoints, true)[0];
+ const touch = InteractionUtils.GetMyTargetTouches(me, this.prevPoints, true)[0];
+ console.log("down");
+ if (touch) {
this._downX = touch.clientX;
this._downY = touch.clientY;
- this._hitTemplateDrag = false;
- for (let element = (e.target as any); element && !this._hitTemplateDrag; element = element.parentElement) {
- if (element.className && element.className.toString() === "collectionViewBaseChrome-collapse") {
- this._hitTemplateDrag = true;
+ if (!e.nativeEvent.cancelBubble) {
+ this._hitTemplateDrag = false;
+ for (let element = (e.target as any); element && !this._hitTemplateDrag; element = element.parentElement) {
+ if (element.className && element.className.toString() === "collectionViewBaseChrome-collapse") {
+ this._hitTemplateDrag = true;
+ }
}
+ if ((this.active || this.Document.onDragStart || this.Document.onClick) && !e.ctrlKey && !this.Document.lockedPosition && !this.Document.inOverlay) e.stopPropagation();
+ this.removeMoveListeners();
+ this.addMoveListeners();
+ this.removeEndListeners();
+ this.addEndListeners();
+ e.stopPropagation();
}
- if ((this.active || this.Document.onDragStart || this.Document.onClick) && !e.ctrlKey && !this.Document.lockedPosition && !this.Document.inOverlay) e.stopPropagation();
- this.removeMoveListeners();
- this.addMoveListeners();
- this.removeEndListeners();
- this.addEndListeners();
- e.stopPropagation();
}
}
@@ -710,6 +713,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
subitems.push({ description: "Open Alias Tab ", event: () => this.props.addDocTab(Doc.MakeAlias(this.props.Document), this.props.DataDoc, "inTab"), icon: "folder" });
subitems.push({ description: "Open Alias Right", event: () => this.props.addDocTab(Doc.MakeAlias(this.props.Document), this.props.DataDoc, "onRight"), icon: "caret-square-right" });
subitems.push({ description: "Open Fields ", event: () => this.props.addDocTab(Docs.Create.KVPDocument(this.props.Document, { _width: 300, _height: 300 }), undefined, "onRight"), icon: "layer-group" });
+ subitems.push({ description: "Open Repl", icon: "laptop-code", event: () => OverlayView.Instance.addWindow(<ScriptingRepl />, { x: 300, y: 100, width: 200, height: 200, title: "Scripting REPL" }) });
cm.addItem({ description: "Open...", subitems: subitems, icon: "external-link-alt" });
@@ -761,8 +765,6 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
moreItems.push({ description: "Tag Child Images via Google Photos", event: () => GooglePhotos.Query.TagChildImages(this.props.Document), icon: "caret-square-right" });
moreItems.push({ description: "Write Back Link to Album", event: () => GooglePhotos.Transactions.AddTextEnrichment(this.props.Document), icon: "caret-square-right" });
}
- moreItems.push({ description: "Pin to Presentation", event: () => this.props.pinToPres(this.props.Document), icon: "map-pin" }); //I think this should work... and it does! A miracle!
- moreItems.push({ description: "Add Repl", icon: "laptop-code", event: () => OverlayView.Instance.addWindow(<ScriptingRepl />, { x: 300, y: 100, width: 200, height: 200, title: "Scripting REPL" }) });
moreItems.push({
description: "Download document", icon: "download", event: async () =>
console.log(JSON.parse(await rp.get(Utils.CorsProxy("http://localhost:8983/solr/dash/select"), {
@@ -820,6 +822,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
}
});
const path = this.props.LibraryPath.reduce((p: string, d: Doc) => p + "/" + (Doc.AreProtosEqual(d, (Doc.UserDoc().LibraryBtn as Doc).sourcePanel as Doc) ? "" : d.title), "");
+ cm.addItem({ description: "Pin to Presentation", event: () => this.props.pinToPres(this.props.Document), icon: "map-pin" });
cm.addItem({
description: `path: ${path}`, event: () => {
this.props.LibraryPath.map(lp => Doc.GetProto(lp).treeViewOpen = lp.treeViewOpen = true);
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index 0d97c3029..fe9b8e0ff 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -379,7 +379,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
specificContextMenu = (e: React.MouseEvent): void => {
const funcs: ContextMenuProps[] = [];
- funcs.push({ description: "Toggle Sidebar", event: () => { e.stopPropagation(); this.toggleSidebar(); }, icon: "expand-arrows-alt" });
+ funcs.push({ description: "Toggle Sidebar", event: () => { e.stopPropagation(); this.props.Document._showSidebar = !this.props.Document._showSidebar }, icon: "expand-arrows-alt" });
funcs.push({ description: "Record Bullet", event: () => { e.stopPropagation(); this.recordBullet(); }, icon: "expand-arrows-alt" });
["My Text", "Text from Others", "Todo Items", "Important Items", "Ignore Items", "Disagree Items", "By Recent Minute", "By Recent Hour"].forEach(option =>
funcs.push({
@@ -1062,15 +1062,15 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
}
@computed get sidebarWidthPercent() { return StrCast(this.props.Document.sidebarWidthPercent, "0%"); }
- @computed get sidebarWidth() { return Number(this.sidebarWidthPercent.substring(0, this.sidebarWidthPercent.length - 1)) / 100 * this.props.PanelWidth(); }
+ sidebarWidth = () => { return Number(this.sidebarWidthPercent.substring(0, this.sidebarWidthPercent.length - 1)) / 100 * this.props.PanelWidth(); }
+ sidebarScreenToLocal = () => this.props.ScreenToLocalTransform().translate(-(this.props.PanelWidth() - this.sidebarWidth()), 0);
@computed get sidebarColor() { return StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], "transparent")); }
render() {
TraceMobx();
const rounded = StrCast(this.layoutDoc.borderRounding) === "100%" ? "-rounded" : "";
const interactive = InkingControl.Instance.selectedTool || this.layoutDoc.isBackground;
if (this.props.isSelected()) {
- // TODO: ftong --> update from dash in richtextmenu
- RichTextMenu.Instance.updateFromDash(this._editorView!, undefined, this.props);
+ this._editorView && RichTextMenu.Instance.updateFromDash(this._editorView, undefined, this.props);
} else if (FormattedTextBoxComment.textBox === this) {
FormattedTextBoxComment.Hide();
}
@@ -1101,13 +1101,13 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
<div className={`formattedTextBox-outer`} style={{ width: `calc(100% - ${this.sidebarWidthPercent})`, }} ref={this._scrollRef}>
<div className={`formattedTextBox-inner${rounded}`} style={{ whiteSpace: "pre-wrap", pointerEvents: ((this.Document.isButton || this.props.onClick) && !this.props.isSelected()) ? "none" : undefined }} ref={this.createDropTarget} />
</div>
- {this.props.Document._hideSidebar ? (null) : this.sidebarWidthPercent === "0%" ?
+ {this.props.Document._showSidebar ? (null) : this.sidebarWidthPercent === "0%" ?
<div className="formattedTextBox-sidebar-handle" onPointerDown={this.sidebarDown} onClick={e => this.toggleSidebar()} /> :
<div className={"formattedTextBox-sidebar" + (InkingControl.Instance.selectedTool !== InkTool.None ? "-inking" : "")}
style={{ width: `${this.sidebarWidthPercent}`, backgroundColor: `${this.sidebarColor}` }}>
<CollectionFreeFormView {...this.props}
PanelHeight={this.props.PanelHeight}
- PanelWidth={() => this.sidebarWidth}
+ PanelWidth={this.sidebarWidth}
annotationsKey={this.annotationKey}
isAnnotationOverlay={false}
focus={this.props.focus}
@@ -1118,9 +1118,9 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
whenActiveChanged={this.whenActiveChanged}
removeDocument={this.removeDocument}
moveDocument={this.moveDocument}
- addDocument={(doc: Doc) => { doc._hideSidebar = true; return this.addDocument(doc); }}
+ addDocument={this.addDocument}
CollectionView={undefined}
- ScreenToLocalTransform={() => this.props.ScreenToLocalTransform().translate(-(this.props.PanelWidth() - this.sidebarWidth), 0)}
+ ScreenToLocalTransform={this.sidebarScreenToLocal}
renderDepth={this.props.renderDepth + 1}
ContainingCollectionDoc={this.props.ContainingCollectionDoc}
chromeCollapsed={true}>
diff --git a/src/client/views/nodes/PresBox.scss b/src/client/views/nodes/PresBox.scss
index e5a79ab11..01e7f4834 100644
--- a/src/client/views/nodes/PresBox.scss
+++ b/src/client/views/nodes/PresBox.scss
@@ -6,7 +6,7 @@
top: 0;
bottom: 0;
width: 100%;
- min-width: 200px;
+ min-width: 100px;
height: 100%;
min-height: 50px;
letter-spacing: 2px;
@@ -16,8 +16,6 @@
.presBox-listCont {
position: relative;
- padding-left: 10px;
- padding-right: 10px;
}
.presBox-buttons {
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index 428e9aa7b..8d53f45a6 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -42,7 +42,7 @@ export class PresBox extends React.Component<FieldViewProps> {
if (value) {
value.forEach((item, i) => {
if (item instanceof Doc && item.type !== DocumentType.PRESELEMENT) {
- const pinDoc = Docs.Create.PresElementBoxDocument({ backgroundColor: "transparent" });
+ const pinDoc = Docs.Create.PresElementBoxDocument({ backgroundColor: "transparent", _xMargin: 5 });
Doc.GetProto(pinDoc).presentationTargetDoc = item;
Doc.GetProto(pinDoc).title = ComputedField.MakeFunction('this.presentationTargetDoc?.title?.toString()');
value.splice(i, 1, pinDoc);
@@ -337,7 +337,7 @@ export class PresBox extends React.Component<FieldViewProps> {
@action
initializeScaleViews = (docList: Doc[], viewtype: number) => {
this.props.Document._chromeStatus = "disabled";
- const hgt = (viewtype === CollectionViewType.Tree) ? 50 : 72;
+ const hgt = (viewtype === CollectionViewType.Tree) ? 50 : 42;
docList.forEach((doc: Doc) => {
doc.presBox = this.props.Document;
doc.presBoxKey = this.props.fieldKey;
@@ -357,7 +357,7 @@ export class PresBox extends React.Component<FieldViewProps> {
}
getTransform = () => {
- return this.props.ScreenToLocalTransform().translate(-10, -50);// listBox padding-left and pres-box-cont minHeight
+ return this.props.ScreenToLocalTransform().translate(0, -50);// listBox padding-left and pres-box-cont minHeight
}
render() {
this.initializeScaleViews(this.childDocs, NumCast(this.props.Document._viewType));
diff --git a/src/client/views/presentationview/PresElementBox.scss b/src/client/views/presentationview/PresElementBox.scss
index 34c170be2..b74b07224 100644
--- a/src/client/views/presentationview/PresElementBox.scss
+++ b/src/client/views/presentationview/PresElementBox.scss
@@ -6,14 +6,17 @@
width: 100%;
outline-color: maroon;
outline-style: dashed;
- border-radius: 12px;
+ border-radius: 6px;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
- transition: all .1s;
+ transition: all .1s;
+ padding: 0px;
+ padding-left: 5px;
+ padding-bottom: 3px;
.documentView-node {
position: absolute;
@@ -32,34 +35,43 @@
.presElementBox-item:hover {
transition: all .1s;
background: #AAAAAA;
- border-radius: 12px;
+ border-radius: 6px;
}
.presElementBox-selected {
background: gray;
color: black;
- border-radius: 12px;
+ border-radius: 6px;
box-shadow: black 2px 2px 5px;
}
.presElementBox-closeIcon {
- float: right;
border-radius: 20px;
transform:scale(0.7);
+ position: absolute;
+ right: 0;
+ top: 0;
+ padding: 8px;
}
.presElementBox-interaction {
color: gray;
float: left;
+ padding: 0px;
+ width: 20px;
+ height: 20px;
}
.presElementBox-interaction-selected {
color: white;
float: left;
+ padding: 0px;
+ width: 22px;
+ height: 22px;
}
.presElementBox-name {
- font-size: 15px;
+ font-size: 12px;
position: absolute;
display: inline-block;
width: calc(100% - 45px);
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index 5f454e930..5f78636a9 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -611,7 +611,7 @@ export namespace Doc {
Cast(templateField.data, listSpec(Doc), [])?.map(d => d instanceof Doc && MakeMetadataFieldTemplate(d, templateDoc));
(Doc.GetProto(templateField)[metadataFieldKey] = ObjectField.MakeCopy(templateField.data));
}
- if (templateField.data instanceof RichTextField && templateField.data.Data) {
+ if (templateField.data instanceof RichTextField && templateField.data.Text) {
templateField._textTemplate = ComputedField.MakeFunction(`copyField(this.${metadataFieldKey})`, { this: Doc.name });
}
diff --git a/src/pen-gestures/ndollar.ts b/src/pen-gestures/ndollar.ts
index ef5ca38c6..9e15ada2d 100644
--- a/src/pen-gestures/ndollar.ts
+++ b/src/pen-gestures/ndollar.ts
@@ -168,7 +168,12 @@ export class NDollarRecognizer {
//
this.Multistrokes = new Array(NumMultistrokes);
this.Multistrokes[0] = new Multistroke(GestureUtils.Gestures.Box, useBoundedRotationInvariance, new Array(
- new Array(new Point(30, 146), new Point(30, 222), new Point(106, 225), new Point(106, 146), new Point(30, 146))
+ new Array(
+ new Point(30, 146), //new Point(29, 160), new Point(30, 180), new Point(31, 200),
+ new Point(30, 222), //new Point(50, 219), new Point(70, 225), new Point(90, 230),
+ new Point(106, 225), //new Point(100, 200), new Point(106, 180), new Point(110, 160),
+ new Point(106, 146), //new Point(80, 150), new Point(50, 146),
+ new Point(30, 143))
));
this.Multistrokes[1] = new Multistroke(GestureUtils.Gestures.Line, useBoundedRotationInvariance, new Array(
new Array(new Point(12, 347), new Point(119, 347))
diff --git a/src/server/authentication/models/current_user_utils.ts b/src/server/authentication/models/current_user_utils.ts
index 35b266608..6bfc729de 100644
--- a/src/server/authentication/models/current_user_utils.ts
+++ b/src/server/authentication/models/current_user_utils.ts
@@ -55,7 +55,7 @@ export class CurrentUserUtils {
{ title: "cat image", icon: "cat", ignoreClick: true, drag: 'Docs.Create.ImageDocument("https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg", { _width: 200, title: "an image of a cat" })' },
{ title: "record", icon: "microphone", ignoreClick: true, drag: `Docs.Create.AudioDocument("${nullAudio}", { _width: 200, title: "ready to record audio" })` },
{ title: "clickable button", icon: "bolt", ignoreClick: true, drag: 'Docs.Create.ButtonDocument({ _width: 150, _height: 50, title: "Button" })' },
- { title: "presentation", icon: "tv", ignoreClick: true, drag: `Doc.UserDoc().curPresentation = Docs.Create.PresDocument(new List<Doc>(), { _width: 200, _height: 500, _viewType: ${CollectionViewType.Stacking}, title: "a presentation trail" })` },
+ { title: "presentation", icon: "tv", ignoreClick: true, drag: `Doc.UserDoc().curPresentation = Docs.Create.PresDocument(new List<Doc>(), { _width: 200, _height: 500, _xMargin:5, _viewType: ${CollectionViewType.Stacking}, title: "a presentation trail" })` },
{ title: "import folder", icon: "cloud-upload-alt", ignoreClick: true, drag: 'Docs.Create.DirectoryImportDocument({ title: "Directory Import", _width: 400, _height: 400 })' },
{ title: "mobile view", icon: "phone", ignoreClick: true, drag: 'Doc.UserDoc().activeMobile' },
{ title: "use pen", icon: "pen-nib", click: 'activatePen(this.activePen.pen = sameDocs(this.activePen.pen, this) ? undefined : this,2, this.backgroundColor)', backgroundColor: "blue", ischecked: `sameDocs(this.activePen.pen, this)`, activePen: doc },
@@ -116,7 +116,8 @@ export class CurrentUserUtils {
{ title: "use pen", icon: "pen-nib", pointerUp: "resetPen()", pointerDown: 'setPen(2, this.backgroundColor)', backgroundColor: "blue", ischecked: `sameDocs(this.activePen.pen, this)`, activePen: doc },
{ title: "use highlighter", icon: "highlighter", pointerUp: "resetPen()", pointerDown: 'setPen(20, this.backgroundColor)', backgroundColor: "yellow", ischecked: `sameDocs(this.activePen.pen, this)`, activePen: doc },
{ title: "notepad", icon: "clipboard", pointerUp: "GestureOverlay.Instance.closeFloatingDoc()", pointerDown: 'GestureOverlay.Instance.openFloatingDoc(this.clipboard)', clipboard: Docs.Create.FreeformDocument([], { _width: 300, _height: 300 }), backgroundColor: "orange", ischecked: `sameDocs(this.activePen.pen, this)`, activePen: doc },
- { title: "interpret text", icon: "font", pointerUp: "setToolglass('none')", pointerDown: "setToolglass('inktotext')", clipboard: Docs.Create.FreeformDocument([], { _width: 300, _height: 300 }), backgroundColor: "orange", ischecked: `sameDocs(this.activePen.pen, this)`, activePen: doc },
+ { title: "interpret text", icon: "font", pointerUp: "setToolglass('none')", pointerDown: "setToolglass('inktotext')", backgroundColor: "orange", ischecked: `sameDocs(this.activePen.pen, this)`, activePen: doc },
+ { title: "ignore gestures", icon: "signature", pointerUp: "setToolglass('none')", pointerDown: "setToolglass('ignoregesture')", backgroundColor: "green", ischecked: `sameDocs(this.activePen.pen, this)`, activePen: doc },
];
return docProtoData.map(data => Docs.Create.FontIconDocument({
_nativeWidth: 10, _nativeHeight: 10, _width: 10, _height: 10, _dropAction: data.pointerDown ? "copy" : undefined, title: data.title, icon: data.icon, ignoreClick: data.ignoreClick,