aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/collections/collectionFreeForm
diff options
context:
space:
mode:
authorAubrey-Li <aubreylys@hotmail.com>2022-04-26 16:16:28 -0400
committerAubrey-Li <aubreylys@hotmail.com>2022-04-26 16:16:28 -0400
commit313c761f4207d55ebda05c18c2bd4a42539fdfe0 (patch)
tree94d5716089bb5815fff02cc08d3b08f8ae1e30f8 /src/client/views/collections/collectionFreeForm
parentd935a8c1aad3fa6acaa4522aeb667afaaeddc60c (diff)
parentf4b6942fc1cad1f7e7ec7552e22f6c56bc158a77 (diff)
Merge branch master into presentation_upgrade
Diffstat (limited to 'src/client/views/collections/collectionFreeForm')
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx30
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx62
-rw-r--r--src/client/views/collections/collectionFreeForm/MarqueeView.scss1
-rw-r--r--src/client/views/collections/collectionFreeForm/MarqueeView.tsx11
4 files changed, 74 insertions, 30 deletions
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
index 9fed82dae..16c7df311 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
@@ -111,23 +111,25 @@ export function computerStarburstLayout(
viewDefsToJSX: (views: ViewDefBounds[]) => ViewDefResult[],
engineProps: any
) {
+ const mustFit = pivotDoc[WidthSym]() !== panelDim[0]; // if a panel size is set that's not the same as the pivot doc's size, then assume this is in a panel for a content fitting view (like a grid) in which case everything must be scaled to stay within the panel
const docMap = new Map<string, PoolData>();
- const burstRadius = [NumCast(pivotDoc._starburstRadius, panelDim[0]), NumCast(pivotDoc._starburstRadius, panelDim[1])];
- const docScale = NumCast(pivotDoc._starburstDocScale);
- const docSize = docScale * 100; // assume a icon sized at 100
- const scaleDim = [burstRadius[0] + docSize, burstRadius[1] + docSize];
+ const docSize = mustFit ? panelDim[0] * .33 : 75; // assume an icon sized at 75
+ const burstRadius = mustFit ? panelDim : [NumCast(pivotDoc._starburstRadius, panelDim[0]) - docSize, NumCast(pivotDoc._starburstRadius, panelDim[1]) - docSize];
+ const scaleDim = [burstRadius[0] * 2 + docSize, burstRadius[1] * 2 + docSize];
childPairs.forEach(({ layout, data }, i) => {
+ const docSize = layout.layoutKey === "layout_icon" ? (mustFit ? panelDim[0] * .33 : 75) : 400; // assume a icon sized at 75
const deg = i / childPairs.length * Math.PI * 2;
docMap.set(layout[Id], {
- x: Math.cos(deg) * (burstRadius[0] / 3) - docScale * layout[WidthSym]() / 2,
- y: Math.sin(deg) * (burstRadius[1] / 3) - docScale * layout[HeightSym]() / 2,
- width: docScale * layout[WidthSym](),
- height: docScale * layout[HeightSym](),
+ x: Math.cos(deg) * burstRadius[0] - docSize / 2,
+ y: Math.sin(deg) * burstRadius[1] - docSize * layout[HeightSym]() / layout[WidthSym]() / 2,
+ width: docSize,//layout[WidthSym](),
+ height: docSize * layout[HeightSym]() / layout[WidthSym](),
+ zIndex: NumCast(layout.zIndex),
pair: { layout, data },
replica: ""
});
});
- const divider = { type: "div", color: "transparent", x: -burstRadius[0] / 3, y: 0, width: 15, height: 15, payload: undefined };
+ const divider = { type: "div", color: "transparent", x: -burstRadius[0], y: 0, width: 15, height: 15, payload: undefined };
return normalizeResults(scaleDim, 12, docMap, poolData, viewDefsToJSX, [], 0, [divider]);
}
@@ -265,7 +267,13 @@ export function computePivotLayout(
});
const dividers = sortedPivotKeys.map((key, i) =>
- ({ type: "div", color: "lightGray", x: i * pivotAxisWidth * (numCols * expander + gap) - pivotAxisWidth * (expander - 1) / 2, y: -maxColHeight + pivotAxisWidth, width: pivotAxisWidth * numCols * expander, height: maxColHeight, payload: pivotColumnGroups.get(key)!.filters }));
+ ({
+ type: "div", color: "lightGray",
+ x: i * pivotAxisWidth * (numCols * expander + gap) - pivotAxisWidth * (expander - 1) / 2,
+ y: -maxColHeight + pivotAxisWidth, width: pivotAxisWidth * numCols * expander,
+ height: maxColHeight,
+ payload: pivotColumnGroups.get(key)!.filters
+ }));
groupNames.push(...dividers);
return normalizeResults(panelDim, max_text, docMap, poolData, viewDefsToJSX, groupNames, 0, []);
}
@@ -402,7 +410,7 @@ function normalizeResults(
const grpEles = groupNames.map(gn => ({ x: gn.x, y: gn.y, width: gn.width, height: gn.height }) as ViewDefBounds);
const docEles = Array.from(docMap.entries()).map(ele => ele[1]);
const aggBounds = aggregateBounds(extras.concat(grpEles.concat(docEles.map(de => ({ ...de, type: "doc", payload: "" })))).filter(e => e.zIndex !== -99), 0, 0);
- aggBounds.r = Math.max(minWidth, aggBounds.r - aggBounds.x);
+ aggBounds.r = aggBounds.x + Math.max(minWidth, aggBounds.r - aggBounds.x);
const wscale = panelDim[0] / (aggBounds.r - aggBounds.x);
let scale = wscale * (aggBounds.b - aggBounds.y) > panelDim[1] ? (panelDim[1]) / (aggBounds.b - aggBounds.y) : wscale;
if (Number.isNaN(scale)) scale = 1;
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index b2697cf08..bdae5a4f8 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -9,6 +9,7 @@ import { InkData, InkField, InkTool, PointData, Segment } from "../../../../fiel
import { List } from "../../../../fields/List";
import { ObjectField } from "../../../../fields/ObjectField";
import { RichTextField } from "../../../../fields/RichTextField";
+import { ImageField } from "../../../../fields/URLField";
import { createSchema, listSpec } from "../../../../fields/Schema";
import { ScriptField } from "../../../../fields/ScriptField";
import { BoolCast, Cast, FieldValue, NumCast, ScriptCast, StrCast } from "../../../../fields/Types";
@@ -41,6 +42,8 @@ import { CollectionFreeFormDocumentView } from "../../nodes/CollectionFreeFormDo
import { DocFocusOptions, DocumentView, DocumentViewProps, ViewAdjustment, ViewSpecPrefix } from "../../nodes/DocumentView";
import { FormattedTextBox } from "../../nodes/formattedText/FormattedTextBox";
import { PresBox } from "../../nodes/trails/PresBox";
+import { VideoBox } from "../../nodes/VideoBox";
+import { CreateImage } from "../../nodes/WebBoxRenderer";
import { StyleLayers, StyleProp } from "../../StyleProvider";
import { CollectionDockingView } from "../CollectionDockingView";
import { CollectionSubView } from "../CollectionSubView";
@@ -451,9 +454,11 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
e.preventDefault();
break;
case InkTool.None:
- this._hitCluster = this.pickCluster(this.getTransform().transformPoint(e.clientX, e.clientY));
- document.addEventListener("pointermove", this.onPointerMove);
- document.addEventListener("pointerup", this.onPointerUp);
+ if (!(this.props.layoutEngine?.() || StrCast(this.layoutDoc._layoutEngine))) {
+ this._hitCluster = this.pickCluster(this.getTransform().transformPoint(e.clientX, e.clientY));
+ document.addEventListener("pointermove", this.onPointerMove);
+ document.addEventListener("pointerup", this.onPointerUp);
+ }
break;
}
}
@@ -1011,8 +1016,8 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
} else if (doc.isInkMask) {
doc.zIndex = 5000;
} else {
- const docs = this.childLayoutPairs.map(pair => pair.layout);
- docs.slice().sort((doc1, doc2) => NumCast(doc1.zIndex) - NumCast(doc2.zIndex));
+ const docs = this.childLayoutPairs.map(pair => pair.layout).slice();
+ docs.sort((doc1, doc2) => NumCast(doc1.zIndex) - NumCast(doc2.zIndex));
let zlast = docs.length ? Math.max(docs.length, NumCast(docs[docs.length - 1].zIndex)) : 1;
if (zlast - docs.length > 100) {
for (let i = 0; i < docs.length; i++) doc.zIndex = i + 1;
@@ -1058,11 +1063,10 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
this.props.focus(doc, options);
} else {
const xfToCollection = options?.docTransform ?? Transform.Identity();
- const layoutdoc = Doc.Layout(doc);
const savedState = { panX: NumCast(this.Document._panX), panY: NumCast(this.Document._panY), scale: this.Document[this.scaleFieldKey] };
const newState = HistoryUtil.getState();
const cantTransform = this.props.isAnnotationOverlay || ((this.rootDoc._isGroup || this.layoutDoc._lockedTransform) && !LightboxView.LightboxDoc);
- const { panX, panY, scale } = cantTransform ? savedState : this.calculatePanIntoView(layoutdoc, xfToCollection, options?.willZoom ? options?.scale || .75 : undefined);
+ const { panX, panY, scale } = cantTransform ? savedState : this.calculatePanIntoView(doc, xfToCollection, options?.willZoom ? options?.scale || .75 : undefined);
if (!cantTransform) { // only pan and zoom to focus on a document if the document is not an annotation in an annotation overlay collection
newState.initializers![this.Document[Id]] = { panX: panX, panY: panY };
HistoryUtil.pushState(newState);
@@ -1109,10 +1113,11 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
}
calculatePanIntoView = (doc: Doc, xf: Transform, scale?: number) => {
+ const layoutdoc = Doc.Layout(doc);
const pw = this.props.PanelWidth() / NumCast(this.layoutDoc._viewScale, 1);
const ph = this.props.PanelHeight() / NumCast(this.layoutDoc._viewScale, 1);
const pt = xf.transformPoint(NumCast(doc.x), NumCast(doc.y));
- const pt2 = xf.transformPoint(NumCast(doc.x) + doc[WidthSym](), NumCast(doc.y) + doc[HeightSym]());
+ const pt2 = xf.transformPoint(NumCast(doc.x) + layoutdoc[WidthSym](), NumCast(doc.y) + layoutdoc[HeightSym]());
const bounds = { left: pt[0], right: pt2[0], top: pt[1], bot: pt2[1] };
const cx = NumCast(this.layoutDoc._panX);
const cy = NumCast(this.layoutDoc._panY);
@@ -1142,7 +1147,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
isContentActive = () => this.props.isSelected() || this.props.isContentActive();
- getChildDocView(entry: PoolData, renderIndex: number) {
+ getChildDocView(entry: PoolData) {
const childLayout = entry.pair.layout;
const childData = entry.pair.data;
const engine = this.props.layoutEngine?.() || StrCast(this.props.Document._layoutEngine);
@@ -1151,8 +1156,8 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
Document={childLayout}
renderDepth={this.props.renderDepth + 1}
replica={entry.replica}
- renderIndex={renderIndex}
dataTransition={entry.transition}
+ suppressSetHeight={this.layoutEngine ? true : false}
renderCutoffProvider={this.renderCutoffProvider}
ContainingCollectionView={this.props.CollectionView}
ContainingCollectionDoc={this.props.Document}
@@ -1295,10 +1300,11 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
return [] as ViewDefResult[];
}
+ @computed get layoutEngine() { return this.props.layoutEngine?.() || StrCast(this.layoutDoc._layoutEngine); }
@computed get doInternalLayoutComputation() {
TraceMobx();
const newPool = new Map<string, PoolData>();
- switch (this.props.layoutEngine?.() || StrCast(this.layoutDoc._layoutEngine)) {
+ switch (this.layoutEngine) {
case "pass": return { newPool, computedElementData: this.doEngineLayout(newPool, computerPassLayout) };
case "timeline": return { newPool, computedElementData: this.doEngineLayout(newPool, computeTimelineLayout) };
case "pivot": return { newPool, computedElementData: this.doEngineLayout(newPool, computePivotLayout) };
@@ -1328,7 +1334,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
const elements = computedElementData.slice();
Array.from(newPool.entries()).filter(entry => this.isCurrent(entry[1].pair.layout)).forEach((entry, i) =>
elements.push({
- ele: this.getChildDocView(entry[1], i),
+ ele: this.getChildDocView(entry[1]),
bounds: this.childDataProvider(entry[1].pair.layout, entry[1].replica)
}));
@@ -1411,6 +1417,37 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
}));
}
+ updateIcon = () => {
+ this.props.docViewPath().lastElement().ContentDiv!.style.width = (this.layoutDoc[WidthSym]()).toString();
+ this.props.docViewPath().lastElement().ContentDiv!.style.height = (this.layoutDoc[HeightSym]()).toString();
+ const htmlString = this._mainCont && new XMLSerializer().serializeToString(this.props.docViewPath().lastElement().ContentDiv!);
+ this.props.docViewPath().lastElement().ContentDiv!.style.width = "";
+ this.props.docViewPath().lastElement().ContentDiv!.style.height = "";
+ const nativeWidth = this.layoutDoc[WidthSym]();
+ const nativeHeight = this.layoutDoc[HeightSym]();
+
+ CreateImage(
+ "",
+ document.styleSheets,
+ htmlString?.replace(/docView-hack/g, 'documentView-hack'),
+ nativeWidth,
+ nativeWidth * this.props.PanelHeight() / this.props.PanelWidth(),
+ NumCast(this.layoutDoc._scrollTop)
+ ).then
+ ((data_url: any) => {
+ VideoBox.convertDataUri(data_url, this.layoutDoc[Id] + "-icon" + (new Date()).getTime(), true, this.layoutDoc[Id] + "-icon").then(
+ returnedfilename => setTimeout(action(() => {
+
+ this.dataDoc.icon = new ImageField(returnedfilename);
+ this.dataDoc["icon-nativeWidth"] = nativeWidth;
+ this.dataDoc["icon-nativeHeight"] = nativeHeight;
+ }), 500));
+ })
+ .catch(function (error: any) {
+ console.error('oops, something went wrong!', error);
+ });
+ }
+
componentWillUnmount() {
Object.values(this._disposers).forEach(disposer => disposer?.());
this._marqueeRef.current?.removeEventListener("dashDragAutoScroll", this.onDragAutoScroll as any);
@@ -1476,6 +1513,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
appearanceItems.push({ description: "Reset View", event: () => { this.props.Document._panX = this.props.Document._panY = 0; this.props.Document[this.scaleFieldKey] = 1; }, icon: "compress-arrows-alt" });
!Doc.UserDoc().noviceMode && Doc.UserDoc().defaultTextLayout && appearanceItems.push({ description: "Reset default note style", event: () => Doc.UserDoc().defaultTextLayout = undefined, icon: "eye" });
appearanceItems.push({ description: `${this.fitToContent ? "Make Zoomable" : "Scale to Window"}`, event: () => this.Document._fitToBox = !this.fitToContent, icon: !this.fitToContent ? "expand-arrows-alt" : "compress-arrows-alt" });
+ appearanceItems.push({ description: `update icon`, event: this.updateIcon, icon: "compress-arrows-alt" });
this.props.ContainingCollectionView &&
appearanceItems.push({ description: "Ungroup collection", event: this.promoteCollection, icon: "table" });
!Doc.UserDoc().noviceMode ? appearanceItems.push({ description: "Arrange contents in grid", event: this.layoutDocsInGrid, icon: "table" }) : null;
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.scss b/src/client/views/collections/collectionFreeForm/MarqueeView.scss
index 62510ce9d..41e4d6b6a 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.scss
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.scss
@@ -10,6 +10,7 @@
user-select: none;
}
+
.marqueeView:focus-within {
overflow: hidden;
}
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index e10273523..afdb91633 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -562,15 +562,12 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
d.y = NumCast(d.y) - this.Bounds.top;
return d;
});
- const summary = Docs.Create.TextDocument("", { x: this.Bounds.left, y: this.Bounds.top, _width: 200, _height: 200, _fitToBox: true, _showSidebar: true, title: "overview" });
- const portal = Doc.MakeAlias(summary);
- Doc.GetProto(summary)[Doc.LayoutFieldKey(summary) + "-annotations"] = new List<Doc>(selected);
- Doc.GetProto(summary).layout_portal = CollectionView.LayoutString(Doc.LayoutFieldKey(summary) + "-annotations");
- summary._backgroundColor = "#e2ad32";
- portal.layoutKey = "layout_portal";
- portal.title = "document collection";
+ const summary = Docs.Create.TextDocument("", { _backgroundColor: "#e2ad32", x: this.Bounds.left, y: this.Bounds.top, isPushpin: true, _width: 200, _height: 200, _fitToBox: true, _showSidebar: true, title: "overview" });
+ const portal = Docs.Create.FreeformDocument(selected, { x: this.Bounds.left + 200, y: this.Bounds.top, isGroup: true, backgroundColor: "transparent" });
DocUtils.MakeLink({ doc: summary }, { doc: portal }, "summarizing", "");
+ portal.hidden = true;
+ this.props.addDocument?.(portal);
this.props.addLiveTextDocument(summary);
MarqueeOptionsMenu.Instance.fadeOut(true);
}