aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/DocumentView.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/nodes/DocumentView.tsx')
-rw-r--r--src/client/views/nodes/DocumentView.tsx62
1 files changed, 42 insertions, 20 deletions
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 3d6b53ccc..30d5a5184 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -1,6 +1,6 @@
import { IconProp } from '@fortawesome/fontawesome-svg-core';
import { Dropdown, DropdownType, Type } from 'browndash-components';
-import { action, computed, IReactionDisposer, observable, reaction, runInAction } from 'mobx';
+import { action, computed, IReactionDisposer, observable, reaction, runInAction, trace } from 'mobx';
import { observer } from 'mobx-react';
import { computedFn } from 'mobx-utils';
import { Bounce, Fade, Flip, LightSpeed, Roll, Rotate, Zoom } from 'react-reveal';
@@ -136,7 +136,7 @@ export interface DocComponentView {
componentUI?: (boundsLeft: number, boundsTop: number) => JSX.Element | null;
incrementalRendering?: () => void;
layout_fitWidth?: () => boolean; // whether the component always fits width (eg, KeyValueBox)
- overridePointerEvents?: () => 'all' | 'none' | undefined; // if the conmponent overrides the pointer events for the document
+ overridePointerEvents?: () => 'all' | 'none' | undefined; // if the conmponent overrides the pointer events for the document (e.g, KeyValueBox always allows pointer events)
fieldKey?: string;
annotationKey?: string;
getTitle?: () => string;
@@ -272,8 +272,9 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
return this._animateScaleTime ?? 100;
}
public get displayName() {
- return 'DocumentView(' + this.props.Document.title + ')';
+ return 'DocumentViewInternal(' + this.props.Document.title + ')';
} // this makes mobx trace() statements more descriptive
+
public get ContentDiv() {
return this._mainCont.current;
}
@@ -317,8 +318,10 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
@computed get titleHeight() {
return this.props?.styleProvider?.(this.layoutDoc, this.props, StyleProp.TitleHeight) || 0;
}
+ @observable _pointerEvents: 'none' | 'all' | 'visiblePainted' | undefined;
@computed get pointerEvents(): 'none' | 'all' | 'visiblePainted' | undefined {
- return this.props.styleProvider?.(this.Document, this.props, StyleProp.PointerEvents);
+ TraceMobx();
+ return this._pointerEvents;
}
@computed get finalLayoutKey() {
return StrCast(this.Document.layout_fieldKey, 'layout');
@@ -330,6 +333,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
return this.props.NativeHeight();
}
@computed get disableClickScriptFunc() {
+ TraceMobx();
const onScriptDisable = this.props.onClickScriptDisable ?? this._componentView?.onClickScriptDisable?.() ?? this.layoutDoc.onClickScriptDisable;
// prettier-ignore
return (
@@ -356,6 +360,25 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
}
componentDidMount() {
this.setupHandlers();
+ this._disposers.contentActive = reaction(
+ () => {
+ // true - if the document has been activated directly or indirectly (by having its children selected)
+ // false - if its pointer events are explicitly turned off or if it's container tells it that it's inactive
+ // undefined - it is not active, but it should be responsive to actions that might activate it or its contents (eg clicking)
+ return this.props.isContentActive() === false || this.props.pointerEvents?.() === 'none'
+ ? false
+ : Doc.ActiveTool !== InkTool.None || SnappingManager.GetCanEmbed() || this.rootSelected() || this.rootDoc.forceActive || this._componentView?.isAnyChildContentActive?.() || this.props.isContentActive()
+ ? true
+ : undefined;
+ },
+ active => (this._isContentActive = active),
+ { fireImmediately: true }
+ );
+ this._disposers.pointerevents = reaction(
+ () => this.props.styleProvider?.(this.Document, this.props, StyleProp.PointerEvents),
+ pointerevents => (this._pointerEvents = pointerevents),
+ { fireImmediately: true }
+ );
}
preDropFunc = (e: Event, de: DragManager.DropEvent) => {
const dropAction = this.layoutDoc.dropAction as dropActionType;
@@ -883,23 +906,22 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
onClickFunc: any = () => (this.disableClickScriptFunc ? undefined : this.onClickHandler);
setHeight = (height: number) => (this.layoutDoc._height = height);
setContentView = action((view: { getAnchor?: (addAsAnnotation: boolean) => Doc; forward?: () => boolean; back?: () => boolean }) => (this._componentView = view));
- @computed get _isContentActive() {
- // true - if the document has been activated directly or indirectly (by having its children selected)
- // false - if its pointer events are explicitly turned off or if it's container tells it that it's inactive
- // undefined - it is not active, but it should be responsive to actions that might active it or its contents (eg clicking)
- return this.props.isContentActive() === false || this.props.pointerEvents?.() === 'none'
- ? false
- : Doc.ActiveTool !== InkTool.None || SnappingManager.GetIsDragging() || this.rootSelected() || this.rootDoc.forceActive || this._componentView?.isAnyChildContentActive?.() || this.props.isContentActive()
- ? true
- : undefined;
- }
+ @observable _isContentActive: boolean | undefined;
+
isContentActive = (): boolean | undefined => this._isContentActive;
childFilters = () => [...this.props.childFilters(), ...StrListCast(this.layoutDoc.childFilters)];
/// disable pointer events on content when there's an enabled onClick script (but not the browse script) and the contents aren't forced active, or if contents are marked inactive
@computed get _contentPointerEvents() {
- if (this.props.contentPointerEvents) return this.props.contentPointerEvents;
- return (!this.disableClickScriptFunc && this.onClickHandler && !this.props.onBrowseClick?.() && this.isContentActive() !== true) || this.isContentActive() === false ? 'none' : this.pointerEvents;
+ TraceMobx();
+ return this.props.contentPointerEvents ??
+ ((!this.disableClickScriptFunc && //
+ this.onClickHandler &&
+ !this.props.onBrowseClick?.() &&
+ this.isContentActive() !== true) ||
+ this.isContentActive() === false)
+ ? 'none'
+ : this.pointerEvents;
}
contentPointerEvents = () => this._contentPointerEvents;
@computed get contents() {
@@ -1304,8 +1326,8 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
onContextMenu={this.onContextMenu}
onPointerDown={this.onPointerDown}
onClick={this.onClick}
- onPointerEnter={e => (!SnappingManager.GetIsDragging() || DragManager.CanEmbed) && Doc.BrushDoc(this.rootDoc)}
- onPointerOver={e => (!SnappingManager.GetIsDragging() || DragManager.CanEmbed) && Doc.BrushDoc(this.rootDoc)}
+ onPointerEnter={e => (!SnappingManager.GetIsDragging() || SnappingManager.GetCanEmbed()) && Doc.BrushDoc(this.rootDoc)}
+ onPointerOver={e => (!SnappingManager.GetIsDragging() || SnappingManager.GetCanEmbed()) && Doc.BrushDoc(this.rootDoc)}
onPointerLeave={e => !isParentOf(this.ContentDiv, document.elementFromPoint(e.nativeEvent.x, e.nativeEvent.y)) && Doc.UnBrushDoc(this.rootDoc)}
style={{
borderRadius: this.borderRounding,
@@ -1426,9 +1448,9 @@ export class DocumentView extends React.Component<DocumentViewProps> {
@computed get hideLinkButton() {
return this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.HideLinkBtn + (this.isSelected() ? ':selected' : ''));
}
+ hideLinkCount = () => this.props.renderDepth === -1 || (this.isSelected() && this.props.renderDepth) || !this._isHovering || this.hideLinkButton;
@computed get linkCountView() {
- const hideCount = this.props.renderDepth === -1 || SnappingManager.GetIsDragging() || (this.isSelected() && this.props.renderDepth) || !this._isHovering || this.hideLinkButton;
- return hideCount ? null : <DocumentLinksButton View={this} scaling={this.scaleToScreenSpace} OnHover={true} Bottom={this.topMost} ShowCount={true} />;
+ return <DocumentLinksButton hideCount={this.hideLinkCount} View={this} scaling={this.scaleToScreenSpace} OnHover={true} Bottom={this.topMost} ShowCount={true} />;
}
@computed get docViewPath(): DocumentView[] {
return this.props.docViewPath ? [...this.props.docViewPath(), this] : [this];