aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/StyleProvider.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/StyleProvider.tsx')
-rw-r--r--src/client/views/StyleProvider.tsx286
1 files changed, 152 insertions, 134 deletions
diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx
index dcec2fe3d..3842f930a 100644
--- a/src/client/views/StyleProvider.tsx
+++ b/src/client/views/StyleProvider.tsx
@@ -1,3 +1,6 @@
+/* eslint-disable jsx-a11y/alt-text */
+/* eslint-disable jsx-a11y/no-static-element-interactions */
+/* eslint-disable jsx-a11y/click-events-have-key-events */
import { IconProp } from '@fortawesome/fontawesome-svg-core';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Tooltip } from '@mui/material';
@@ -7,54 +10,23 @@ import { extname } from 'path';
import * as React from 'react';
import { BsArrowDown, BsArrowDownUp, BsArrowUp } from 'react-icons/bs';
import { FaFilter } from 'react-icons/fa';
+import { ClientUtils, DashColor, lightOrDark } from '../../ClientUtils';
import { Doc, Opt, StrListCast } from '../../fields/Doc';
-import { DocViews } from '../../fields/DocSymbols';
+import { Id } from '../../fields/FieldSymbols';
+import { ScriptField } from '../../fields/ScriptField';
import { BoolCast, Cast, DocCast, ImageCast, NumCast, ScriptCast, StrCast } from '../../fields/Types';
-import { DashColor, lightOrDark, Utils } from '../../Utils';
+import { AudioAnnoState } from '../../server/SharedMediaTypes';
import { CollectionViewType, DocumentType } from '../documents/DocumentTypes';
-import { DocFocusOrOpen, DocumentManager } from '../util/DocumentManager';
-import { IsFollowLinkScript } from '../util/LinkFollower';
-import { LinkManager } from '../util/LinkManager';
-import { SettingsManager } from '../util/SettingsManager';
+import { IsFollowLinkScript } from '../documents/DocUtils';
import { SnappingManager } from '../util/SnappingManager';
import { undoBatch, UndoManager } from '../util/UndoManager';
-import { CollectionSchemaView } from './collections/collectionSchema/CollectionSchemaView';
import { TreeSort } from './collections/TreeSort';
import { Colors } from './global/globalEnums';
-import { DocumentViewProps } from './nodes/DocumentView';
+import { DocumentView, DocumentViewProps } from './nodes/DocumentView';
import { FieldViewProps } from './nodes/FieldView';
-import { KeyValueBox } from './nodes/KeyValueBox';
-import { PropertiesView } from './PropertiesView';
+import { StyleProp } from './StyleProp';
import './StyleProvider.scss';
-
-export enum StyleProp {
- TreeViewIcon = 'treeView_Icon',
- TreeViewSortings = 'treeView_Sortings', // options for how to sort tree view items
- DocContents = 'docContents', // when specified, the JSX returned will replace the normal rendering of the document view
- Opacity = 'opacity', // opacity of the document view
- BoxShadow = 'boxShadow', // box shadow - used for making collections standout and for showing clusters in free form views
- BorderRounding = 'borderRounding', // border radius of the document view
- Color = 'color', // foreground color of Document view items
- BackgroundColor = 'backgroundColor', // background color of a document view
- FillColor = 'fillColor', // fill color of an ink stroke or shape
- WidgetColor = 'widgetColor', // color to display UI widgets on a document view -- used for the sidebar divider dragger on a text note
- PointerEvents = 'pointerEvents', // pointer events for DocumentView -- inherits pointer events if not specified
- Decorations = 'decorations', // additional decoration to display above a DocumentView -- currently only used to display a Lock for making things background
- HeaderMargin = 'headerMargin', // margin at top of documentview, typically for displaying a title -- doc contents will start below that
- ShowCaption = 'layout_showCaption',
- TitleHeight = 'titleHeight', // Height of Title area
- ShowTitle = 'layout_showTitle', // whether to display a title on a Document (optional :hover suffix)
- BorderPath = 'customBorder', // border path for document view
- FontSize = 'fontSize', // size of text font
- FontFamily = 'fontFamily', // font family of text
- FontWeight = 'fontWeight', // font weight of text
- Highlighting = 'highlighting', // border highlighting
-}
-
-export enum AudioAnnoState {
- stopped = 'stopped',
- playing = 'playing',
-}
+import { emptyPath } from '../../Utils';
function toggleLockedPosition(doc: Doc) {
UndoManager.RunInBatch(() => Doc.toggleLockedPosition(doc), 'toggleBackground');
@@ -70,6 +42,19 @@ function togglePaintView(e: React.MouseEvent, doc: Opt<Doc>, props: Opt<FieldVie
ScriptCast(doc?.onPaint)?.script.run(scriptProps);
}
+export function styleFromLayoutString(doc: Doc, props: FieldViewProps, scale: number) {
+ const style: { [key: string]: any } = {};
+ const divKeys = ['width', 'height', 'fontSize', 'transform', 'left', 'backgroundColor', 'left', 'right', 'top', 'bottom', 'pointerEvents', 'position'];
+ const replacer = (match: any, expr: string) =>
+ // bcz: this executes a script to convert a property expression string: { script } into a value
+ ScriptField.MakeFunction(expr, { this: Doc.name, scale: 'number' })?.script.run({ this: doc, scale }).result?.toString() ?? '';
+ divKeys.forEach((prop: string) => {
+ const p = (props as any)[prop];
+ typeof p === 'string' && (style[prop] = p?.replace(/{([^.'][^}']+)}/g, replacer));
+ });
+ return style;
+}
+
export function wavyBorderPath(pw: number, ph: number, inset: number = 0.05) {
return `M ${pw * 0.5} ${ph * inset} C ${pw * 0.6} ${ph * inset} ${pw * (1 - 2 * inset)} 0 ${pw * (1 - inset)} ${ph * inset} C ${pw} ${ph * (2 * inset)} ${pw * (1 - inset)} ${ph * 0.25} ${pw * (1 - inset)} ${ph * 0.3} C ${
pw * (1 - inset)
@@ -80,6 +65,11 @@ export function wavyBorderPath(pw: number, ph: number, inset: number = 0.05) {
} ${ph * inset}`;
}
+let _filterOpener: () => void;
+export function SetFilterOpener(func: () => void) {
+ _filterOpener = func;
+}
+
// a preliminary implementation of a dash style sheet for setting rendering properties of documents nested within a Tab
//
export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps & DocumentViewProps>, property: string): any {
@@ -90,38 +80,61 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps &
const isNonTransparentLevel = isNonTransparent ? Number(property.replace(/.*:nonTransparent([0-9]+).*/, '$1')) : 0; // property.includes(':nonTransparent');
const isAnnotated = property.includes(':annotated');
const layoutDoc = doc ? Doc.Layout(doc) : doc;
- const isInk = () => layoutDoc?._layout_isSvg && !props?.LayoutTemplateString;
- const isOpen = property.includes(':open');
- const isEmpty = property.includes(':empty');
- const boxBackground = property.includes(':box');
- const fieldKey = props?.fieldKey ? props.fieldKey + '_' : isCaption ? 'caption_' : '';
+ const isOpen = property.includes(':treeOpen');
+ const boxBackground = property.includes(':docView'); // background color of docView's bounds can be different than the background of contents -- eg FontIconBox
+ const {
+ DocumentView: docView,
+ fieldKey: fieldKeyProp,
+ styleProvider,
+ pointerEvents,
+ isGroupActive,
+ isDocumentActive,
+ containerViewPath,
+ childFilters,
+ hideCaptions,
+ showTitle,
+ childFiltersByRanges,
+ renderDepth,
+ docViewPath,
+ LayoutTemplateString,
+ disableBrushing,
+ NativeDimScaling,
+ PanelWidth,
+ PanelHeight,
+ isSelected,
+ } = props || {}; // extract props that are not shared between fieldView and documentView props.
+ const componentView = docView?.()?.ComponentView;
+ const fieldKey = fieldKeyProp ? fieldKeyProp + '_' : isCaption ? 'caption_' : '';
+ const isInk = () => layoutDoc?._layout_isSvg && !LayoutTemplateString;
const lockedPosition = () => doc && BoolCast(doc._lockedPosition);
- const titleHeight = () => props?.styleProvider?.(doc, props, StyleProp.TitleHeight);
- const backgroundCol = () => props?.styleProvider?.(doc, props, StyleProp.BackgroundColor + ':nonTransparent' + (isNonTransparentLevel + 1));
- const color = () => props?.styleProvider?.(doc, props, StyleProp.Color);
- const opacity = () => props?.styleProvider?.(doc, props, StyleProp.Opacity);
- const layout_showTitle = () => props?.styleProvider?.(doc, props, StyleProp.ShowTitle);
+ const titleHeight = () => styleProvider?.(doc, props, StyleProp.TitleHeight);
+ const backgroundCol = () => styleProvider?.(doc, props, StyleProp.BackgroundColor + ':nonTransparent' + (isNonTransparentLevel + 1));
+ const color = () => styleProvider?.(doc, props, StyleProp.Color);
+ const opacity = () => styleProvider?.(doc, props, StyleProp.Opacity);
+ const layoutShowTitle = () => styleProvider?.(doc, props, StyleProp.ShowTitle);
// prettier-ignore
switch (property.split(':')[0]) {
- case StyleProp.TreeViewIcon:
- const img = ImageCast(doc?.icon, ImageCast(doc?.data));
+ case StyleProp.TreeViewIcon: {
+ const img = ImageCast(doc?.icon ?? doc?.[doc ? Doc.LayoutFieldKey(doc) : ""]);
if (img) {
const ext = extname(img.url.href);
const url = doc?.icon ? img.url.href : img.url.href.replace(ext, '_s' + ext);
return <img src={url} width={20} height={15} style={{ margin: 'auto', display: 'block', objectFit: 'contain' }} />;
}
return Doc.toIcon(doc, isOpen);
- case StyleProp.TreeViewSortings:
+ }
+ case StyleProp.TreeViewSortings: {
const allSorts: { [key: string]: { color: string; icon: JSX.Element | string } | undefined } = {};
allSorts[TreeSort.AlphaDown] = { color: Colors.MEDIUM_BLUE, icon: <BsArrowDown/> };
allSorts[TreeSort.AlphaUp] = { color: 'crimson', icon: <BsArrowUp/> };
if (doc?._type_collection === CollectionViewType.Freeform) allSorts[TreeSort.Zindex] = { color: 'green', icon: 'Z' };
allSorts[TreeSort.WhenAdded] = { color: 'darkgray', icon: <BsArrowDownUp/> };
return allSorts;
+ }
case StyleProp.Highlighting:
if (doc && (Doc.IsSystem(doc) || doc.type === DocumentType.FONTICON)) return undefined;
- if (doc && !doc.layout_disableBrushing && !props?.disableBrushing) {
- const selected = Array.from(doc?.[DocViews]??[]).filter(dv => dv.IsSelected).length;
+ if (doc && !doc.layout_disableBrushing && !disableBrushing) {
+ const selected = DocumentView.getViews(doc).filter(dv => dv.IsSelected).length;
const highlightIndex = Doc.GetBrushHighlightStatus(doc) || (selected ? Doc.DocBrushStatus.selfBrushed : 0);
const highlightColor = ['transparent', 'rgb(68, 118, 247)', selected ? "black" : 'rgb(68, 118, 247)', 'orange', 'lightBlue'][highlightIndex];
const highlightStyle = ['solid', 'dashed', 'solid', 'solid', 'solid'][highlightIndex];
@@ -135,71 +148,74 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps &
}
}
return undefined;
- case StyleProp.DocContents:return undefined;
- case StyleProp.WidgetColor:return isAnnotated ? Colors.LIGHT_BLUE : 'dimgrey';
- case StyleProp.Opacity: return props?.LayoutTemplateString?.includes(KeyValueBox.name) ? 1 : doc?.text_inlineAnnotations ? 0 : Cast(doc?._opacity, "number", Cast(doc?.opacity, 'number', null));
- case StyleProp.FontSize: return StrCast(doc?.[fieldKey + 'fontSize'], StrCast(Doc.UserDoc().fontSize));
- case StyleProp.FontFamily: return StrCast(doc?.[fieldKey + 'fontFamily'], StrCast(Doc.UserDoc().fontFamily));
- case StyleProp.FontWeight: return StrCast(doc?.[fieldKey + 'fontWeight'], StrCast(Doc.UserDoc().fontWeight));
- case StyleProp.FillColor: return StrCast(doc?._fillColor, StrCast(doc?.fillColor, StrCast(doc?.backgroundColor, 'transparent')));
- case StyleProp.ShowCaption:return props?.hideCaptions || doc?._type_collection === CollectionViewType.Carousel ? undefined: StrCast(doc?._layout_showCaption);
- case StyleProp.TitleHeight:return Math.min(4,(props?.DocumentView?.().screenToViewTransform().Scale ?? 1)) * NumCast(Doc.UserDoc().headerHeight,30);
+ case StyleProp.DocContents: return undefined;
+ case StyleProp.WidgetColor: return isAnnotated ? Colors.LIGHT_BLUE : 'dimgrey';
+ case StyleProp.Opacity: return componentView?.isUnstyledView?.() ? 1 : Cast(doc?._opacity, "number", Cast(doc?.opacity, 'number', null));
+ case StyleProp.FontColor: return StrCast(doc?.[fieldKey + 'fontColor'], StrCast(Doc.UserDoc().fontColor, color()));
+ case StyleProp.FontSize: return StrCast(doc?.[fieldKey + 'fontSize'], StrCast(Doc.UserDoc().fontSize));
+ case StyleProp.FontFamily: return StrCast(doc?.[fieldKey + 'fontFamily'], StrCast(Doc.UserDoc().fontFamily));
+ case StyleProp.FontWeight: return StrCast(doc?.[fieldKey + 'fontWeight'], StrCast(Doc.UserDoc().fontWeight));
+ case StyleProp.FillColor: return StrCast(doc?._fillColor, StrCast(doc?.fillColor, StrCast(doc?.backgroundColor, 'transparent')));
+ case StyleProp.ShowCaption: return hideCaptions || doc?._type_collection === CollectionViewType.Carousel ? undefined: StrCast(doc?._layout_showCaption);
+ case StyleProp.TitleHeight: return Math.min(4,(docView?.().screenToViewTransform().Scale ?? 1)) * NumCast(Doc.UserDoc().headerHeight,30);
case StyleProp.ShowTitle:
return (
(doc &&
- !(props?.DocumentView?.().ComponentView instanceof CollectionSchemaView) &&
- !props?.LayoutTemplateString &&
+ !componentView?.isUnstyledView?.() &&
+ !LayoutTemplateString &&
!doc.presentation_targetDoc &&
- !props?.LayoutTemplateString?.includes(KeyValueBox.name) &&
- props?.layout_showTitle?.() !== '' &&
+ showTitle?.() !== '' &&
StrCast(
doc._layout_showTitle,
- props?.layout_showTitle?.() ||
+ showTitle?.() ||
(!Doc.IsSystem(doc) && [DocumentType.COL, DocumentType.FUNCPLOT, DocumentType.LABEL, DocumentType.RTF, DocumentType.IMG, DocumentType.VID].includes(doc.type as any)
- ? doc.author === Doc.CurrentUserEmail
+ ? doc.author === ClientUtils.CurrentUserEmail()
? StrCast(Doc.UserDoc().layout_showTitle)
: remoteDocHeader
: '')
)) ||
''
);
- case StyleProp.Color:
- if (SettingsManager.Instance.LastPressedBtn === doc) return SettingsManager.userBackgroundColor;
- if (Doc.IsSystem(doc!)) return SettingsManager.userColor;
- if (doc?.type === DocumentType.FONTICON) return SettingsManager.userColor;
+ case StyleProp.Color: {
+ if (SnappingManager.LastPressedBtn === doc?.[Id]) return SnappingManager.userBackgroundColor;
+ if (Doc.IsSystem(doc!)) return SnappingManager.userColor;
+ if (doc?.type === DocumentType.FONTICON) return SnappingManager.userColor;
const docColor: Opt<string> = StrCast(doc?.[fieldKey + 'color'], StrCast(doc?._color));
if (docColor) return docColor;
const backColor = backgroundCol();
return backColor ? lightOrDark(backColor) : undefined;
- case StyleProp.BorderRounding:
+ }
+ case StyleProp.BorderRounding: {
const rounding = StrCast(doc?.[fieldKey + 'borderRounding'], StrCast(doc?.layout_borderRounding, doc?._type_collection === CollectionViewType.Pile ? '50%' : ''));
return (doc?.[StrCast(doc?.layout_fieldKey)] instanceof Doc || doc?.isTemplateDoc) ? StrCast(doc._layout_borderRounding,rounding) : rounding;
- case StyleProp.BorderPath:
+ }
+ case StyleProp.BorderPath: {
const borderPath = Doc.IsComicStyle(doc) &&
- props?.renderDepth &&
- !doc?.layout_isSvg && { path: wavyBorderPath(props?.PanelWidth?.() || 0, props?.PanelHeight?.() || 0), fill: wavyBorderPath(props?.PanelWidth?.() || 0, props?.PanelHeight?.() || 0, 0.08), width: 3 };
- return !borderPath
- ? null
- : {
- clipPath: `path('${borderPath.path}')`,
- jsx: (
- <div key="border2" className="documentView-customBorder" style={{ pointerEvents: 'none' }}>
- <svg style={{ overflow: 'visible', height: '100%' }} viewBox={`0 0 ${props.PanelWidth()} ${props.PanelHeight()}`}>
- <path d={borderPath.path} style={{ stroke: 'black', fill: 'transparent', strokeWidth: borderPath.width }} />
- </svg>
- </div>
- ),
- };
+ renderDepth &&
+ !doc?.layout_isSvg && { path: wavyBorderPath(PanelWidth?.() || 0, PanelHeight?.() || 0), fill: wavyBorderPath(PanelWidth?.() || 0, PanelHeight?.() || 0, 0.08), width: 3 };
+ return !borderPath
+ ? null
+ : {
+ clipPath: `path('${borderPath.path}')`,
+ jsx: (
+ <div key="border2" className="documentView-customBorder" style={{ pointerEvents: 'none' }}>
+ <svg style={{ overflow: 'visible', height: '100%' }} viewBox={`0 0 ${PanelWidth?.()} ${PanelHeight?.()}`}>
+ <path d={borderPath.path} style={{ stroke: 'black', fill: 'transparent', strokeWidth: borderPath.width }} />
+ </svg>
+ </div>
+ ),
+ };
+ }
case StyleProp.HeaderMargin:
return ([CollectionViewType.Stacking, CollectionViewType.NoteTaking, CollectionViewType.Masonry, CollectionViewType.Tree].includes(doc?._type_collection as any) ||
- (doc?.type === DocumentType.RTF && !layout_showTitle()?.includes('noMargin')) ||
+ (doc?.type === DocumentType.RTF && !layoutShowTitle()?.includes('noMargin')) ||
doc?.type === DocumentType.LABEL) &&
- layout_showTitle() &&
+ layoutShowTitle() &&
!StrCast(doc?.layout_showTitle).includes(':hover')
? titleHeight()
: 0;
case StyleProp.BackgroundColor: {
- if (SettingsManager.Instance.LastPressedBtn === doc) return SettingsManager.userColor; // hack to indicate active menu panel item
+ 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;
@@ -224,47 +240,48 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps &
case DocumentType.VID: docColor = docColor || (Colors.LIGHT_GRAY); break;
case DocumentType.COL:
docColor = docColor || (doc && Doc.IsSystem(doc)
- ? SettingsManager.userBackgroundColor
+ ? SnappingManager.userBackgroundColor
: doc?.annotationOn
? '#00000010' // faint interior for collections on PDFs, images, etc
: doc?.isGroup
? undefined
: doc?._type_collection === CollectionViewType.Stacking ?
(Colors.DARK_GRAY)
- : Cast((props?.renderDepth || 0) > 0 ? Doc.UserDoc().activeCollectionNestedBackground : Doc.UserDoc().activeCollectionBackground, 'string') ?? (Colors.MEDIUM_GRAY));
+ : Cast((renderDepth || 0) > 0 ? Doc.UserDoc().activeCollectionNestedBackground : Doc.UserDoc().activeCollectionBackground, 'string') ?? (Colors.MEDIUM_GRAY));
break;
- //if (doc._type_collection !== CollectionViewType.Freeform && doc._type_collection !== CollectionViewType.Time) return "rgb(62,62,62)";
+ // if (doc._type_collection !== CollectionViewType.Freeform && doc._type_collection !== CollectionViewType.Time) return "rgb(62,62,62)";
default: docColor = docColor || (Colors.WHITE);
}
- if (isNonTransparent && isNonTransparentLevel < 9 && (!docColor || docColor === 'transparent') && doc?.embedContainer && props?.styleProvider) {
- return props.styleProvider(DocCast(doc.embedContainer), props, StyleProp.BackgroundColor+":nonTransparent"+(isNonTransparentLevel+1));
+ if (isNonTransparent && isNonTransparentLevel < 9 && (!docColor || docColor === 'transparent') && doc?.embedContainer && styleProvider) {
+ return styleProvider(DocCast(doc.embedContainer), props, StyleProp.BackgroundColor+":nonTransparent"+(isNonTransparentLevel+1));
}
return (docColor && !doc) ? DashColor(docColor).fade(0.5).toString() : docColor;
}
case StyleProp.BoxShadow: {
if (!doc || opacity() === 0 || doc.noShadow) return undefined; // if it's not visible, then no shadow)
if (doc.layout_boxShadow === 'standard') return Shadows.STANDARD_SHADOW;
- if (IsFollowLinkScript(doc?.onClick) && LinkManager.Links(doc).length && !layoutDoc?.layout_isSvg) return StrCast(doc?._linkButtonShadow, 'lightblue 0em 0em 1em');
+ if (IsFollowLinkScript(doc?.onClick) && Doc.Links(doc).length && !layoutDoc?.layout_isSvg) return StrCast(doc?._linkButtonShadow, 'lightblue 0em 0em 1em');
switch (doc?.type) {
case DocumentType.COL:
return StrCast(
doc?.layout_boxShadow,
doc?._type_collection === CollectionViewType.Pile
? '4px 4px 10px 2px'
- : lockedPosition() || doc?.isGroup || props?.LayoutTemplateString
+ : lockedPosition() || doc?.isGroup || LayoutTemplateString
? undefined // groups have no drop shadow -- they're supposed to be "invisible". LayoutString's imply collection is being rendered as something else (e.g., title of a Slide)
: `${Colors.DARK_GRAY} ${StrCast(doc.layout_boxShadow, '0.2vw 0.2vw 0.8vw')}`
);
case DocumentType.LABEL:
if (doc?.annotationOn !== undefined) return 'black 2px 2px 1px';
+ // eslint-disable-next-line no-fallthrough
default:
return doc.z
? `#9c9396 ${StrCast(doc?.layout_boxShadow, '10px 10px 0.9vw')}` // if it's a floating doc, give it a big shadow
- : props?.containerViewPath?.().lastElement()?.Document._freeform_useClusters
- ? `${backgroundCol()} ${StrCast(doc.layout_boxShadow, `0vw 0vw ${(lockedPosition() ? 100 : 50) / (props?.NativeDimScaling?.() || 1)}px`)}` // if it's just in a cluster, make the shadown roughly match the cluster border extent
+ : containerViewPath?.().lastElement()?.Document._freeform_useClusters
+ ? `${backgroundCol()} ${StrCast(doc.layout_boxShadow, `0vw 0vw ${(lockedPosition() ? 100 : 50) / (NativeDimScaling?.() || 1)}px`)}` // if it's just in a cluster, make the shadown roughly match the cluster border extent
: NumCast(doc.group, -1) !== -1
- ? `gray ${StrCast(doc.layout_boxShadow, `0vw 0vw ${(lockedPosition() ? 100 : 50) / (props?.NativeDimScaling?.() || 1)}px`)}` // if it's just in a cluster, make the shadown roughly match the cluster border extent
+ ? `gray ${StrCast(doc.layout_boxShadow, `0vw 0vw ${(lockedPosition() ? 100 : 50) / (NativeDimScaling?.() || 1)}px`)}` // if it's just in a cluster, make the shadown roughly match the cluster border extent
: lockedPosition()
? undefined // if it's a background & has a cluster color, make the shadow spread really big
: fieldKey.includes('_inline') // if doc is an inline document in a text box
@@ -275,33 +292,33 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps &
}
}
case StyleProp.PointerEvents:
- if (StrCast(doc?.pointerEvents) && !props?.LayoutTemplateString?.includes(KeyValueBox.name)) return StrCast(doc!.pointerEvents); // honor pointerEvents field (set by lock button usually) if it's not a keyValue view of the Doc
- if (props?.LayoutTemplateString?.includes(KeyValueBox.name)) return 'all';
+ if (componentView?.dontRegisterView?.()) return 'all';
+ if (StrCast(doc?.pointerEvents)) return StrCast(doc!.pointerEvents); // honor pointerEvents field (set by lock button usually) if it's not a keyValue view of the Doc
if (SnappingManager.ExploreMode || doc?.layout_unrendered) return isInk() ? 'visiblePainted' : 'all';
- if (props?.pointerEvents?.() === 'none') return 'none';
+ if (pointerEvents?.() === 'none') return 'none';
if (opacity() === 0) return 'none';
- if (props?.isGroupActive?.() ) return isInk() ? 'visiblePainted': (doc?.
+ if (isGroupActive?.() ) return isInk() ? 'visiblePainted': (doc?.
isGroup )? undefined: 'all'
- if (props?.isDocumentActive?.()) return isInk() ? 'visiblePainted' : 'all';
+ if (isDocumentActive?.()) return isInk() ? 'visiblePainted' : 'all';
return undefined; // fixes problem with tree view elements getting pointer events when the tree view is not active
- case StyleProp.Decorations:
+ case StyleProp.Decorations: {
const lock = () => doc?.pointerEvents !== 'none' ? null : (
<div className="styleProvider-lock" onClick={() => toggleLockedPosition(doc)}>
<FontAwesomeIcon icon='lock' size="lg" />
</div>
);
const paint = () => !doc?.onPaint ? null : (
- <div className={`styleProvider-paint${props?.DocumentView?.().IsSelected ? "-selected":""}`} onClick={e => togglePaintView(e, doc, props)}>
+ <div className={`styleProvider-paint${isSelected?.() ? "-selected":""}`} onClick={e => togglePaintView(e, doc, props)}>
<FontAwesomeIcon icon='pen' size="lg" />
</div>
);
const filter = () => {
- const dashView = untracked(() => DocumentManager.Instance.getDocumentView(Doc.ActiveDashboard));
+ const dashView = untracked(() => DocumentView.getDocumentView(Doc.ActiveDashboard));
const showFilterIcon =
StrListCast(doc?._childFilters).length || StrListCast(doc?._childFiltersByRanges).length
? 'green' // #18c718bd' //'hasFilter'
- : props?.childFilters?.().filter(f => Utils.IsRecursiveFilter(f) && f !== Utils.noDragDocsFilter).length || props?.childFiltersByRanges().length
- ? 'orange' //'inheritsFilter'
+ : childFilters?.().filter(f => ClientUtils.IsRecursiveFilter(f) && f !== ClientUtils.noDragDocsFilter).length || childFiltersByRanges?.().length
+ ? 'orange' // 'inheritsFilter'
: undefined;
return !showFilterIcon ? null : (
<div className="styleProvider-filter">
@@ -309,19 +326,14 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps &
type={Type.TERT}
dropdownType={DropdownType.CLICK}
fillWidth
- iconProvider={(active:boolean) => <div className='styleProvider-filterShift'><FaFilter/></div>}
- closeOnSelect={true}
- setSelectedVal={
- action((dv) => {
- (dv as any).select(false);
- (SettingsManager.Instance.propertiesWidth = 250);
- setTimeout(action(() => {
- if (PropertiesView.Instance) {
- PropertiesView.Instance.CloseAll();
- PropertiesView.Instance.openFilters = true;
- }
- }));
- })
+ // eslint-disable-next-line react/no-unstable-nested-components
+ iconProvider={() => <div className='styleProvider-filterShift'><FaFilter/></div>}
+ closeOnSelect
+ setSelectedVal={((dv: DocumentView) => {
+ dv.select(false);
+ SnappingManager.SetPropertiesWidth(250);
+ _filterOpener?.();
+ }) as any // Dropdown assumes values are strings or numbers..
}
size={Size.XSMALL}
width={15}
@@ -329,27 +341,27 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps &
title={showFilterIcon === 'green' ?
"This view is filtered. Click to view/change filters":
"this view inherits filters from one of its parents"}
- color={SettingsManager.userColor}
+ color={SnappingManager.userColor}
background={showFilterIcon}
- items={[ ...(dashView ? [dashView]: []), ...(props?.docViewPath?.()??[])]
+ items={[ ...(dashView ? [dashView]: []), ...(docViewPath?.()??[])]
.filter(dv => StrListCast(dv?.Document.childFilters).length || StrListCast(dv?.Document.childRangeFilters).length)
.map(dv => ({
text: StrCast(dv?.Document.title),
val: dv as any,
- style: {color:SettingsManager.userColor, background:SettingsManager.userBackgroundColor},
+ style: {color:SnappingManager.userColor, background:SnappingManager.userBackgroundColor},
} as IListItemProps)) }
/>
</div>
);
};
const audio = () => {
- const audioAnnoState = (doc: Doc) => StrCast(doc.audioAnnoState, AudioAnnoState.stopped);
- const audioAnnosCount = (doc: Doc) => StrListCast(doc[fieldKey + 'audioAnnotations']).length;
- if (!doc || props?.renderDepth === -1 || !audioAnnosCount(doc)) return null;
+ const audioAnnoState = (audioDoc: Doc) => StrCast(audioDoc.audioAnnoState, AudioAnnoState.stopped);
+ const audioAnnosCount = (audioDoc: Doc) => StrListCast(audioDoc[fieldKey + 'audioAnnotations']).length;
+ if (!doc || renderDepth === -1 || !audioAnnosCount(doc)) return null;
const audioIconColors: { [key: string]: string } = { playing: 'green', stopped: 'blue' };
return (
<Tooltip title={<div>{StrListCast(doc[fieldKey + 'audioAnnotations_text']).lastElement()}</div>}>
- <div className="styleProvider-audio" onPointerDown={() => DocumentManager.Instance.getFirstDocumentView(doc)?.playAnnotation()}>
+ <div className="styleProvider-audio" onPointerDown={() => DocumentView.getFirstDocumentView(doc)?.playAnnotation()}>
<FontAwesomeIcon className="documentView-audioFont" style={{ color: audioIconColors[audioAnnoState(doc)] }} icon='file-audio' size="sm" />
</div>
</Tooltip>
@@ -363,11 +375,13 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps &
{audio()}
</>
);
+ }
+ default:
}
}
export function DashboardToggleButton(doc: Doc, field: string, onIcon: IconProp, offIcon: IconProp, clickFunc?: () => void) {
- const color = SettingsManager.userColor;
+ const color = SnappingManager.userColor;
return (
<IconButton
size={Size.XSMALL}
@@ -389,7 +403,11 @@ export function DashboardStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps>
if (doc && property.split(':')[0] === StyleProp.Decorations) {
return doc._type_collection === CollectionViewType.Docking || Doc.IsSystem(doc)
? null
- : DashboardToggleButton(doc, 'hidden', 'eye-slash', 'eye', () => DocFocusOrOpen(doc, { toggleTarget: true, willZoomCentered: true, zoomScale: 0 }, DocCast(doc?.embedContainer ?? doc?.annotationOn)));
+ : DashboardToggleButton(doc, 'hidden', 'eye-slash', 'eye', () => DocumentView.FocusOrOpen(doc, { toggleTarget: true, willZoomCentered: true, zoomScale: 0 }, DocCast(doc?.embedContainer ?? doc?.annotationOn)));
}
return DefaultStyleProvider(doc, props, property);
}
+
+export function returnEmptyDocViewList() {
+ return emptyPath;
+}