aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2024-05-16 11:28:10 -0400
committerbobzel <zzzman@gmail.com>2024-05-16 11:28:10 -0400
commit41e47a7b7789e8c192fb31188cf549178ec71a22 (patch)
treec94ee8ab0e952d633f21483ec8e450a471d2c925 /src
parentfdd0e62c148fde01c82504700a83fcc56463a68d (diff)
moved isHovering to DocumentView as instance variable instead from FormattedText as a Document field. cleaned up cluster style provider. fixed freeformView to not trigger as many updates when a doc is dropped, and fixed layoutEngines to not return a background or color unless actually set by the engine.
Diffstat (limited to 'src')
-rw-r--r--src/client/views/StyleProvider.tsx2
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormClusters.ts16
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx71
-rw-r--r--src/client/views/nodes/CollectionFreeFormDocumentView.tsx13
-rw-r--r--src/client/views/nodes/DocumentView.tsx2
-rw-r--r--src/client/views/nodes/FieldView.tsx1
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx8
7 files changed, 53 insertions, 60 deletions
diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx
index 3842f930a..557f7db37 100644
--- a/src/client/views/StyleProvider.tsx
+++ b/src/client/views/StyleProvider.tsx
@@ -218,7 +218,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps &
if (SnappingManager.LastPressedBtn === doc?.[Id]) return SnappingManager.userColor; // hack to indicate active menu panel item
const dataKey = doc ? Doc.LayoutFieldKey(doc) : "";
const usePath = StrCast(doc?.[dataKey + "_usePath"]);
- const alternate = usePath.includes(":hover") ? ( doc?.isHovering ? '_' + usePath.replace(":hover","") : "") : usePath ? "_" +usePath:usePath;
+ const alternate = usePath.includes(":hover") ? ( props?.isHovering?.() ? '_' + usePath.replace(":hover","") : "") : usePath ? "_" +usePath:usePath;
let docColor: Opt<string> = StrCast(doc?.[fieldKey+alternate], StrCast(doc?.['backgroundColor' +alternate], isCaption ? 'rgba(0,0,0,0.4)' : ''));
if (doc?.[StrCast(doc?.layout_fieldKey)] instanceof Doc) docColor = StrCast(doc._backgroundColor,docColor)
// prettier-ignore
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormClusters.ts b/src/client/views/collections/collectionFreeForm/CollectionFreeFormClusters.ts
index 26a52cd2a..6415d5225 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormClusters.ts
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormClusters.ts
@@ -2,7 +2,7 @@ import { action, observable } from 'mobx';
import { CollectionFreeFormView } from '.';
import { intersectRect } from '../../../../Utils';
import { Doc, Opt } from '../../../../fields/Doc';
-import { NumCast, StrCast } from '../../../../fields/Types';
+import { Cast, NumCast, StrCast } from '../../../../fields/Types';
import { DocumentType } from '../../../documents/DocumentTypes';
import { DragManager } from '../../../util/DragManager';
import { dropActionType } from '../../../util/DropActionTypes';
@@ -179,7 +179,6 @@ export class CollectionFreeFormClusters {
};
styleProvider = (doc: Opt<Doc>, props: Opt<FieldViewProps>, property: string) => {
- let styleProp = this.viewStyleProvider?.(doc, props, property); // bcz: check 'props' used to be renderDepth + 1
if (doc && this.childDocs?.includes(doc))
switch (property.split(':')[0]) {
case StyleProp.BackgroundColor:
@@ -189,14 +188,9 @@ export class CollectionFreeFormClusters {
if (this._clusterSets.length <= cluster) {
setTimeout(() => doc && this.addDocument(doc));
} else {
- // choose a cluster color from a palette
- const colors = ['#da42429e', '#31ea318c', 'rgba(197, 87, 20, 0.55)', '#4a7ae2c4', 'rgba(216, 9, 255, 0.5)', '#ff7601', '#1dffff', 'yellow', 'rgba(27, 130, 49, 0.55)', 'rgba(0, 0, 0, 0.268)'];
- styleProp = colors[cluster % colors.length];
- const set = this._clusterSets[cluster]?.filter(s => s.backgroundColor);
- // override the cluster color with an explicitly set color on a non-background document. then override that with an explicitly set color on a background document
- set?.forEach(s => {
- styleProp = StrCast(s.backgroundColor);
- });
+ const palette = ['#da42429e', '#31ea318c', 'rgba(197, 87, 20, 0.55)', '#4a7ae2c4', 'rgba(216, 9, 255, 0.5)', '#ff7601', '#1dffff', 'yellow', 'rgba(27, 130, 49, 0.55)', 'rgba(0, 0, 0, 0.268)'];
+ // override palette cluster color with an explicitly set cluster doc color
+ return this._clusterSets[cluster]?.reduce((b, s) => StrCast(s.backgroundColor, b), palette[cluster % palette.length]);
}
}
}
@@ -208,7 +202,7 @@ export class CollectionFreeFormClusters {
break;
default:
}
- return styleProp;
+ return this.viewStyleProvider?.(doc, props, property); // bcz: check 'props' used to be renderDepth + 1
};
tryToSelect = (addToSel: boolean) => {
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 53493a968..cc195385b 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -404,38 +404,40 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
const fromScreenXf = NumCast(refDoc.z) ? this.ScreenToLocalBoxXf() : this.screenToFreeformContentsXf;
const [xpo, ypo] = fromScreenXf.transformPoint(de.x, de.y);
const [x, y] = [xpo - docDragData.offset[0], ypo - docDragData.offset[1]];
- const zsorted = this.childLayoutPairs
- .map(pair => pair.layout)
- .slice()
- .sort((doc1, doc2) => NumCast(doc1.zIndex) - NumCast(doc2.zIndex));
- zsorted.forEach((doc, index) => {
- doc.zIndex = doc.stroke_isInkMask ? 5000 : index + 1;
- });
- const dvals = CollectionFreeFormDocumentView.getValues(refDoc, NumCast(refDoc.activeFrame, 1000));
- const dropPos = this.Document._currentFrame !== undefined ? [NumCast(dvals.x), NumCast(dvals.y)] : [NumCast(refDoc.x), NumCast(refDoc.y)];
-
- docDragData.droppedDocuments.forEach((d, i) => {
- const layoutDoc = Doc.Layout(d);
- const delta = Utils.rotPt(x - dropPos[0], y - dropPos[1], fromScreenXf.Rotate);
- if (this.Document._currentFrame !== undefined) {
- CollectionFreeFormDocumentView.setupKeyframes([d], NumCast(this.Document._currentFrame), false);
- const pvals = CollectionFreeFormDocumentView.getValues(d, NumCast(d.activeFrame, 1000)); // get filled in values (uses defaults when not value is specified) for position
- const vals = CollectionFreeFormDocumentView.getValues(d, NumCast(d.activeFrame, 1000), false); // get non-default values for everything else
- vals.x = NumCast(pvals.x) + delta.x;
- vals.y = NumCast(pvals.y) + delta.y;
- CollectionFreeFormDocumentView.setValues(NumCast(this.Document._currentFrame), d, vals);
- } else {
- d.x = NumCast(d.x) + delta.x;
- d.y = NumCast(d.y) + delta.y;
- }
- d._layout_modificationDate = new DateField();
- const nd = [Doc.NativeWidth(layoutDoc), Doc.NativeHeight(layoutDoc)];
- layoutDoc._width = NumCast(layoutDoc._width, 300);
- layoutDoc._height = NumCast(layoutDoc._height, nd[0] && nd[1] ? (nd[1] / nd[0]) * NumCast(layoutDoc._width) : 300);
- !d._keepZWhenDragged && (d.zIndex = zsorted.length + 1 + i); // bringToFront
+ runInAction(() => {
+ // needs to be in action to avoid having each edit trigger a freeform layout engine recompute - this triggers just one for each document at the end
+ const zsorted = this.childLayoutPairs
+ .map(pair => pair.layout) //
+ .sort((doc1, doc2) => NumCast(doc1.zIndex) - NumCast(doc2.zIndex));
+ zsorted.forEach((doc, index) => {
+ doc.zIndex = doc.stroke_isInkMask ? 5000 : index + 1;
+ });
+ const dvals = CollectionFreeFormDocumentView.getValues(refDoc, NumCast(refDoc.activeFrame, 1000));
+ const dropPos = this.Document._currentFrame !== undefined ? [NumCast(dvals.x), NumCast(dvals.y)] : [NumCast(refDoc.x), NumCast(refDoc.y)];
+
+ docDragData.droppedDocuments.forEach((d, i) => {
+ const layoutDoc = Doc.Layout(d);
+ const delta = Utils.rotPt(x - dropPos[0], y - dropPos[1], fromScreenXf.Rotate);
+ if (this.Document._currentFrame !== undefined) {
+ CollectionFreeFormDocumentView.setupKeyframes([d], NumCast(this.Document._currentFrame), false);
+ const pvals = CollectionFreeFormDocumentView.getValues(d, NumCast(d.activeFrame, 1000)); // get filled in values (uses defaults when not value is specified) for position
+ const vals = CollectionFreeFormDocumentView.getValues(d, NumCast(d.activeFrame, 1000), false); // get non-default values for everything else
+ vals.x = NumCast(pvals.x) + delta.x;
+ vals.y = NumCast(pvals.y) + delta.y;
+ CollectionFreeFormDocumentView.setValues(NumCast(this.Document._currentFrame), d, vals);
+ } else {
+ d.x = NumCast(d.x) + delta.x;
+ d.y = NumCast(d.y) + delta.y;
+ }
+ d._layout_modificationDate = new DateField();
+ const nd = [Doc.NativeWidth(layoutDoc), Doc.NativeHeight(layoutDoc)];
+ layoutDoc._width = NumCast(layoutDoc._width, 300);
+ layoutDoc._height = NumCast(layoutDoc._height, nd[0] && nd[1] ? (nd[1] / nd[0]) * NumCast(layoutDoc._width) : 300);
+ !d._keepZWhenDragged && (d.zIndex = zsorted.length + 1 + i); // bringToFront
+ });
+ (docDragData.droppedDocuments.length === 1 || de.shiftKey) && this._clusters.addDocuments(docDragData.droppedDocuments);
});
- (docDragData.droppedDocuments.length === 1 || de.shiftKey) && this._clusters.addDocuments(docDragData.droppedDocuments);
return true;
}
@@ -1128,16 +1130,15 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
const rotation = Cast(_rotation,'number',
!this.layoutDoc._rotation_jitter ? null
: NumCast(this.layoutDoc._rotation_jitter) * random(-1, 1, NumCast(x), NumCast(y)) );
- const childProps = { ...this._props, fieldKey: '', styleProvider: this._clusters.styleProvider };
return {
x: isNaN(NumCast(x)) ? 0 : NumCast(x),
y: isNaN(NumCast(y)) ? 0 : NumCast(y),
z: Cast(z, 'number'),
autoDim,
rotation,
- color: Cast(color, 'string') ? StrCast(color) : this._clusters.styleProvider(childDoc, childProps, StyleProp.Color),
- backgroundColor: Cast(backgroundColor, 'string') ? StrCast(backgroundColor) : this._clusters.styleProvider(childDoc, childProps, StyleProp.BackgroundColor),
- opacity: !_width ? 0 : this._keyframeEditing ? 1 : Cast(opacity, 'number') ?? this._clusters.styleProvider?.(childDoc, childProps, StyleProp.Opacity),
+ color: Cast(color, 'string', null),
+ backgroundColor: Cast(backgroundColor, 'string', null),
+ opacity: !_width ? 0 : this._keyframeEditing ? 1 : Cast(opacity, 'number', null),
zIndex: Cast(zIndex, 'number'),
width: _width,
height: _height,
@@ -1209,6 +1210,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
}
doFreeformLayout(poolData: Map<string, PoolData>) {
+ this._clusters.initLayout();
this.childLayoutPairs.filter(pair => this.isCurrent(pair.layout)).map(pair => poolData.set(pair.layout[Id], this.getCalculatedPositions(pair)));
return [] as ViewDefResult[];
}
@@ -1237,7 +1239,6 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
})
);
- this._clusters.initLayout();
return elements;
};
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 62c4cc61a..d65e2d65e 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -126,15 +126,16 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
PanelHeight = () => this._props.autoDim ? this._props.PanelHeight?.() : this.Height; // prettier-ignore
styleProvider = (doc: Doc | undefined, props: Opt<FieldViewProps>, property: string) => {
- if (doc === this.layoutDoc) {
+ const overrideProp = () => {
switch (property.split(':')[0]) {
- case StyleProp.Opacity: return this.Opacity; // only change the opacity for this specific document, not its children
+ case StyleProp.Opacity: return this.Opacity;
case StyleProp.BackgroundColor: return this.BackgroundColor;
case StyleProp.Color: return this.Color;
- default:
- } // prettier-ignore
- }
- return this._props.styleProvider?.(doc, props, property);
+ default: return undefined;
+ }}; // prettier-ignore
+
+ // only override values for this specific document, not any children
+ return (doc === this.layoutDoc && overrideProp()) ?? this._props.styleProvider?.(doc, props, property);
};
public static getValues(doc: Doc, time: number, fillIn: boolean = true) {
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index f56c8288e..66540678d 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -1383,6 +1383,7 @@ export class DocumentView extends DocComponent<DocumentViewProps>() {
PanelHeight = () => this.panelHeight;
NativeDimScaling = () => this.nativeScaling;
hideLinkCount = () => !!this.hideLinkButton;
+ isHovering = () => this._isHovering;
selfView = () => this;
/**
* @returns Transform to the document view (in the coordinate system of whatever contains the DocumentView)
@@ -1449,6 +1450,7 @@ export class DocumentView extends DocComponent<DocumentViewProps>() {
<DocumentViewInternal
{...this._props}
parent={undefined}
+ isHovering={this.isHovering}
fieldKey={this.LayoutFieldKey}
DataTransition={this.DataTransition}
DocumentView={this.selfView}
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index 3f351a072..818d26956 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -91,6 +91,7 @@ export interface FieldViewProps extends FieldViewSharedProps {
docViewPath: () => DocumentView[];
setHeight?: (height: number) => void;
NativeDimScaling?: () => number; // scaling the DocumentView does to transform its contents into its panel & needed by ScreenToLocal
+ isHovering?: () => boolean;
// properties intended to be used from within layout strings (otherwise use the function equivalents that work more efficiently with React)
// See currentUserUtils headerTemplate for examples of creating text boxes from html which set some of these fields
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 93cb67491..de9ba87d3 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -1990,9 +1990,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB
}
@computed get _fieldKey() {
const usePath = this._props.ignoreUsePath ? '' : StrCast(this.layoutDoc[`${this._props.fieldKey}_usePath`]);
- return this._props.fieldKey + (usePath && (!usePath.includes(':hover') || this._isHovering || this._props.isContentActive()) ? `_${usePath.replace(':hover', '')}` : '');
+ return this._props.fieldKey + (usePath && (!usePath.includes(':hover') || this._props.isHovering?.() || this._props.isContentActive()) ? `_${usePath.replace(':hover', '')}` : '');
}
- @observable _isHovering = false;
onPassiveWheel = (e: WheelEvent) => {
if (e.clientX > this.ProseRef!.getBoundingClientRect().right) {
return;
@@ -2038,11 +2037,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB
return styleFromLayout?.height === '0px' ? null : (
<div
className="formattedTextBox"
- onPointerEnter={action(() => {
- this._isHovering = true;
- this.layoutDoc[`_${this._props.fieldKey}_usePath`] && (this.Document.isHovering = true);
- })}
- onPointerLeave={action(() => { this.Document.isHovering = this._isHovering = false; })} // prettier-ignore
ref={r => {
this._oldWheel?.removeEventListener('wheel', this.onPassiveWheel);
this._oldWheel = r;