aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/util/DragManager.ts4
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx42
-rw-r--r--src/client/views/nodes/CollectionFreeFormDocumentView.tsx39
3 files changed, 55 insertions, 30 deletions
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index 601a7e856..c05a2de96 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -94,6 +94,7 @@ export namespace DragManager {
readonly x: number,
readonly y: number,
readonly complete: DragCompleteEvent,
+ readonly shiftKey: boolean,
readonly altKey: boolean,
readonly metaKey: boolean,
readonly ctrlKey: boolean
@@ -340,7 +341,7 @@ export namespace DragManager {
if (dragData instanceof DocumentDragData) {
dragData.userDropAction = e.ctrlKey ? "alias" : undefined;
}
- if (e.shiftKey && CollectionDockingView.Instance) {
+ if (e.shiftKey && CollectionDockingView.Instance && dragData.droppedDocuments.length === 1) {
AbortDrag();
finishDrag?.(new DragCompleteEvent(true, dragData));
CollectionDockingView.Instance.StartOtherDrag({
@@ -409,6 +410,7 @@ export namespace DragManager {
x: e.x,
y: e.y,
complete: complete,
+ shiftKey: e.shiftKey,
altKey: e.altKey,
metaKey: e.metaKey,
ctrlKey: e.ctrlKey
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 4ba58ac84..bac968165 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -155,7 +155,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
this.bringToFront(d);
}));
- de.complete.docDragData.droppedDocuments.length === 1 && this.updateCluster(de.complete.docDragData.droppedDocuments[0]);
+ (de.complete.docDragData.droppedDocuments.length === 1 || de.shiftKey) && this.updateClusterDocs(de.complete.docDragData.droppedDocuments);
}
}
else if (de.complete.annoDragData) {
@@ -213,6 +213,41 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
this.childLayoutPairs.map(pair => pair.layout).map(c => this.updateCluster(c));
}
+ @action
+ updateClusterDocs(docs: Doc[]) {
+ const childLayouts = this.childLayoutPairs.map(pair => pair.layout);
+ if (this.props.Document.useClusters) {
+ const docFirst = docs[0];
+ docs.map(doc => this._clusterSets.map(set => Doc.IndexOf(doc, set) !== -1 && set.splice(Doc.IndexOf(doc, set), 1)));
+ const preferredInd = NumCast(docFirst.cluster);
+ docs.map(doc => doc.cluster = -1);
+ docs.map(doc => this._clusterSets.map((set, i) => set.map(member => {
+ if (docFirst.cluster === -1 && Doc.IndexOf(member, childLayouts) !== -1 && Doc.overlapping(doc, member, this._clusterDistance)) {
+ docFirst.cluster = i;
+ }
+ })));
+ if (docFirst.cluster === -1 && preferredInd !== -1 && (!this._clusterSets[preferredInd] || !this._clusterSets[preferredInd].filter(member => Doc.IndexOf(member, childLayouts) !== -1).length)) {
+ docFirst.cluster = preferredInd;
+ }
+ this._clusterSets.map((set, i) => {
+ if (docFirst.cluster === -1 && !set.filter(member => Doc.IndexOf(member, childLayouts) !== -1).length) {
+ docFirst.cluster = i;
+ }
+ });
+ if (docFirst.cluster === -1) {
+ docs.map(doc => {
+ doc.cluster = this._clusterSets.length;
+ this._clusterSets.push([doc]);
+ });
+ } else {
+ for (let i = this._clusterSets.length; i <= NumCast(docFirst.cluster); i++) !this._clusterSets[i] && this._clusterSets.push([]);
+ docs.map(doc => this._clusterSets[doc.cluster = NumCast(docFirst.cluster)].push(doc));
+ }
+ childLayouts.map(child => !this._clusterSets.some((set, i) => Doc.IndexOf(child, set) !== -1 && child.cluster === i) && this.updateCluster(child));
+ childLayouts.map(child => Doc.GetProto(child).clusterStr = child.cluster?.toString());
+ }
+ }
+
@undoBatch
@action
updateCluster(doc: Doc) {
@@ -270,7 +305,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
return;
}
this._hitCluster = this.props.Document.useClusters ? this.pickCluster(this.getTransform().transformPoint(e.clientX, e.clientY)) !== -1 : false;
- if (e.button === 0 && !e.shiftKey && !e.altKey && !e.ctrlKey && this.props.active(true)) {
+ if (e.button === 0 && (!e.shiftKey || this._hitCluster) && !e.altKey && !e.ctrlKey && this.props.active(true)) {
document.removeEventListener("pointermove", this.onPointerMove);
document.removeEventListener("pointerup", this.onPointerUp);
document.addEventListener("pointermove", this.onPointerMove);
@@ -397,7 +432,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
let x = this.Document._panX || 0;
let y = this.Document._panY || 0;
- const docs = this.childLayoutPairs.map(pair => pair.layout);
+ const docs = this.childLayoutPairs.filter(pair => pair.layout instanceof Doc && !pair.layout.isMinimized).map(pair => pair.layout);
const [dx, dy] = this.getTransform().transformDirection(e.clientX - this._lastX, e.clientY - this._lastY);
if (!this.isAnnotationOverlay && docs.length) {
PDFMenu.Instance.fadeOut(true);
@@ -406,7 +441,6 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
const maxx = this.childDataProvider(docs[0]).width + minx;//docs.length ? NumCast(docs[0].width) + minx : minx;
const maxy = this.childDataProvider(docs[0]).height + miny;//docs.length ? NumCast(docs[0].height) + miny : miny;
const ranges = docs.filter(doc => doc).reduce((range, doc) => {
- const layoutDoc = Doc.Layout(doc);
const x = this.childDataProvider(doc).x;//NumCast(doc.x);
const y = this.childDataProvider(doc).y;//NumCast(doc.y);
const xe = this.childDataProvider(doc).width + x;//x + NumCast(layoutDoc.width);
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 682e43164..3244b7d3e 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -28,6 +28,8 @@ export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps {
@observer
export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeFormDocumentViewProps, PositionDocument>(PositionDocument) {
_disposer: IReactionDisposer | undefined = undefined;
+
+ @observable _animPos: number[] | undefined = undefined;
get displayName() { return "CollectionFreeFormDocumentView(" + this.props.Document.title + ")"; } // this makes mobx trace() statements more descriptive
get transform() { return `scale(${this.props.ContentScaling()}) translate(${this.X}px, ${this.Y}px) rotate(${anime.random(-1, 1) * this.props.jitterRotation}deg)`; }
get X() { return this._animPos !== undefined ? this._animPos[0] : this.renderScriptDim ? this.renderScriptDim.x : this.props.x !== undefined ? this.props.x : this.dataProvider ? this.dataProvider.x : (this.Document.x || 0); }
@@ -56,37 +58,25 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
return undefined;
}
- componentWillUnmount() {
- this._disposer && this._disposer();
- }
+ componentWillUnmount() { this._disposer?.(); }
componentDidMount() {
- this._disposer = reaction(() => this.props.Document.animateToPos ? Array.from(Cast(this.props.Document.animateToPos, listSpec("number"))!) : undefined,
- target => this._animPos = !target ? undefined : target[2] ? [NumCast(this.layoutDoc.x), NumCast(this.layoutDoc.y)] : this.props.ScreenToLocalTransform().transformPoint(target[0], target[1]),
+ this._disposer = reaction(() => Array.from(Cast(this.props.Document?.animateToPos, listSpec("number"), null)),
+ target => this._animPos = !target ? undefined : target[2] ? [NumCast(this.layoutDoc.x), NumCast(this.layoutDoc.y)] :
+ this.props.ScreenToLocalTransform().transformPoint(target[0], target[1]),
{ fireImmediately: true });
}
contentScaling = () => this.nativeWidth > 0 && !this.props.Document.ignoreAspect && !this.props.fitToBox ? this.width / this.nativeWidth : 1;
- panelWidth = () => this.props.PanelWidth();
- panelHeight = () => this.props.PanelHeight();
+ clusterColorFunc = (doc: Doc) => this.clusterColor;
+ panelWidth = () => (this.dataProvider?.width || this.props.PanelWidth());
+ panelHeight = () => (this.dataProvider?.height || this.props.PanelHeight());
getTransform = (): Transform => this.props.ScreenToLocalTransform()
.translate(-this.X, -this.Y)
.scale(1 / this.contentScaling())
- borderRounding = () => {
- const ld = this.layoutDoc[StrCast(this.layoutDoc.layoutKey, "layout")] instanceof Doc ? this.layoutDoc[StrCast(this.layoutDoc.layoutKey, "layout")] as Doc : undefined;
- return StrCast((ld || this.props.Document).borderRounding);
- }
-
@computed
get clusterColor() { return this.props.backgroundColor(this.props.Document); }
- clusterColorFunc = (doc: Doc) => this.clusterColor;
-
- @observable _animPos: number[] | undefined = undefined;
-
- finalPanelWidth = () => (this.dataProvider ? this.dataProvider.width : this.panelWidth());
- finalPanelHeight = () => (this.dataProvider ? this.dataProvider.height : this.panelHeight());
-
render() {
TraceMobx();
return <div className="collectionFreeFormDocumentView-container"
@@ -97,7 +87,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
this.clusterColor ? (`${this.clusterColor} ${StrCast(this.layoutDoc.boxShadow, `0vw 0vw ${(this.layoutDoc.isBackground ? 100 : 50) / this.props.ContentScaling()}px`)}`) : // if it's just in a cluster, make the shadown roughly match the cluster border extent
this.layoutDoc.isBackground ? undefined : // if it's a background & has a cluster color, make the shadow spread really big
StrCast(this.layoutDoc.boxShadow, ""),
- borderRadius: this.borderRounding(),
+ borderRadius: StrCast(Doc.Layout(this.layoutDoc).borderRounding),
transform: this.transform,
transition: this.Document.isAnimating ? ".5s ease-in" : this.props.transition ? this.props.transition : this.dataProvider ? this.dataProvider.transition : StrCast(this.layoutDoc.transition),
width: this.width,
@@ -105,22 +95,21 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
zIndex: this.Document.zIndex || 0,
}} >
-
{!this.props.fitToBox ? <DocumentView {...this.props}
dragDivName={"collectionFreeFormDocumentView-container"}
ContentScaling={this.contentScaling}
ScreenToLocalTransform={this.getTransform}
backgroundColor={this.clusterColorFunc}
- PanelWidth={this.finalPanelWidth}
- PanelHeight={this.finalPanelHeight}
+ PanelWidth={this.panelWidth}
+ PanelHeight={this.panelHeight}
/> : <ContentFittingDocumentView {...this.props}
CollectionDoc={this.props.ContainingCollectionDoc}
DataDocument={this.props.DataDoc}
getTransform={this.getTransform}
active={returnFalse}
focus={(doc: Doc) => this.props.focus(doc, false)}
- PanelWidth={this.finalPanelWidth}
- PanelHeight={this.finalPanelHeight}
+ PanelWidth={this.panelWidth}
+ PanelHeight={this.panelHeight}
/>}
</div>;
}