diff options
Diffstat (limited to 'src/client/views/StyleProvider.tsx')
-rw-r--r-- | src/client/views/StyleProvider.tsx | 95 |
1 files changed, 63 insertions, 32 deletions
diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index 12935400b..f2e1ee0a2 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -1,7 +1,7 @@ import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Tooltip } from '@material-ui/core'; -import { IconButton, Shadows, Size } from 'browndash-components'; +import { Dropdown, DropdownType, IconButton, IListItemProps, ListBox, ListItem, Popup, Shadows, Size, Type } from 'browndash-components'; import { action, runInAction } from 'mobx'; import { extname } from 'path'; import { BsArrowDown, BsArrowDownUp, BsArrowUp } from 'react-icons/bs'; @@ -21,9 +21,10 @@ import { InkingStroke } from './InkingStroke'; import { DocumentView, DocumentViewProps } from './nodes/DocumentView'; import { FieldViewProps } from './nodes/FieldView'; import { KeyValueBox } from './nodes/KeyValueBox'; -import { SliderBox } from './nodes/SliderBox'; import './StyleProvider.scss'; import React = require('react'); +import { PropertiesView } from './PropertiesView'; +import { FaFilter } from 'react-icons/fa'; export enum StyleProp { TreeViewIcon = 'treeView_Icon', @@ -50,10 +51,6 @@ export enum StyleProp { Highlighting = 'highlighting', // border highlighting } -function darkScheme() { - return Doc.ActiveDashboard?.colorScheme === ColorScheme.Dark; -} - function toggleLockedPosition(doc: Doc) { UndoManager.RunInBatch( () => @@ -88,12 +85,14 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps const isCaption = property.includes(':caption'); const isAnchor = property.includes(':anchor'); const isAnnotated = property.includes(':annotated'); + const isInk = () => doc && StrCast(Doc.Layout(doc).layout).includes(InkingStroke.name) && !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 lockedPosition = () => doc && BoolCast(doc._lockedPosition); const backgroundCol = () => props?.styleProvider?.(doc, props, StyleProp.BackgroundColor); + 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); // prettier-ignore @@ -118,7 +117,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps if (doc && !doc.layout_disableBrushing && !props?.disableBrushing) { const selected = SelectionManager.Views().some(dv => dv.rootDoc === doc); const highlightIndex = Doc.isBrushedHighlightedDegree(doc) || (selected ? Doc.DocBrushStatus.selfBrushed : 0); - const highlightColor = ['transparent', 'rgb(68, 118, 247)', selected ? 'black' : 'rgb(68, 118, 247)', 'orange', 'lightBlue'][highlightIndex]; + const highlightColor = ['transparent', 'rgb(68, 118, 247)', selected ? "black" : 'rgb(68, 118, 247)', 'orange', 'lightBlue'][highlightIndex]; const highlightStyle = ['solid', 'dashed', 'solid', 'solid', 'solid'][highlightIndex]; if (highlightIndex) { return { @@ -131,7 +130,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps } return undefined; case StyleProp.DocContents:return undefined; - case StyleProp.WidgetColor:return isAnnotated ? Colors.LIGHT_BLUE : darkScheme() ? 'lightgrey' : 'dimgrey'; + 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.HideLinkBtn:return props?.hideLinkButton || (!selected && doc?.layout_hideLinkButton); case StyleProp.FontSize: return StrCast(doc?.[fieldKey + 'fontSize'], StrCast(doc?._text_fontSize, StrCast(Doc.UserDoc().fontSize))); @@ -143,6 +142,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps case StyleProp.ShowTitle: return ( (doc && + !props?.LayoutTemplateString && !doc.presentation_targetDoc && !props?.LayoutTemplateString?.includes(KeyValueBox.name) && props?.layout_showTitle?.() !== '' && @@ -159,8 +159,8 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps ); case StyleProp.Color: if (DocumentView.LastPressedSidebarBtn === doc) return SettingsManager.userBackgroundColor; - if (Doc.IsSystem(doc!)) return StrCast(Doc.UserDoc().userColor) - if (doc?.type === DocumentType.FONTICON) return Doc.UserDoc().userColor; + if (Doc.IsSystem(doc!)) return SettingsManager.userColor; + if (doc?.type === DocumentType.FONTICON) return SettingsManager.userColor; const docColor: Opt<string> = StrCast(doc?.[fieldKey + 'color'], StrCast(doc?._color)); if (docColor) return docColor; const docView = props?.DocumentView?.(); @@ -193,28 +193,26 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps ? 15 : 0; case StyleProp.BackgroundColor: { - if (DocumentView.LastPressedSidebarBtn === doc) return StrCast(Doc.UserDoc().userColor); // hack to indicate active menu panel item + if (DocumentView.LastPressedSidebarBtn === doc) return SettingsManager.userColor; // hack to indicate active menu panel item let docColor: Opt<string> = StrCast(doc?.[fieldKey + '_backgroundColor'], StrCast(doc?._backgroundColor, isCaption ? 'rgba(0,0,0,0.4)' : '')); // prettier-ignore switch (doc?.type) { - case DocumentType.SLIDER: break; - case DocumentType.PRESELEMENT: docColor = docColor || (darkScheme() ? '' : ''); break; - case DocumentType.PRES: docColor = docColor || (darkScheme() ? 'transparent' : 'transparent'); break; + case DocumentType.PRESELEMENT: docColor = docColor || ""; break; + case DocumentType.PRES: docColor = docColor || 'transparent'; break; case DocumentType.FONTICON: docColor = boxBackground ? undefined : docColor || Colors.DARK_GRAY; break; - case DocumentType.RTF: docColor = docColor || (darkScheme() ? Colors.DARK_GRAY : Colors.LIGHT_GRAY); break; + case DocumentType.RTF: docColor = docColor || Colors.LIGHT_GRAY; break; case DocumentType.INK: docColor = doc?.stroke_isInkMask ? 'rgba(0,0,0,0.7)' : undefined; break; case DocumentType.EQUATION: docColor = docColor || 'transparent'; break; - case DocumentType.LABEL: docColor = docColor || (darkScheme() ? Colors.DARK_GRAY : Colors.LIGHT_GRAY); break; - case DocumentType.BUTTON: docColor = docColor || (darkScheme() ? Colors.DARK_GRAY : Colors.LIGHT_GRAY); break; + case DocumentType.LABEL: docColor = docColor || Colors.LIGHT_GRAY; break; + case DocumentType.BUTTON: docColor = docColor || Colors.LIGHT_GRAY; break; case DocumentType.LINK: docColor = (isAnchor ? docColor : '') || 'transparent'; break; case DocumentType.IMG: case DocumentType.WEB: case DocumentType.PDF: case DocumentType.MAP: case DocumentType.SCREENSHOT: - case DocumentType.VID: docColor = docColor || (darkScheme() ? Colors.DARK_GRAY : Colors.LIGHT_GRAY); break; + case DocumentType.VID: docColor = docColor || (Colors.LIGHT_GRAY); break; case DocumentType.COL: - if (StrCast(Doc.LayoutField(doc)).includes(SliderBox.name)) break; docColor = docColor || (Doc.IsSystem(doc) ? SettingsManager.userBackgroundColor : doc.annotationOn @@ -222,11 +220,11 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps : doc?._isGroup ? undefined : doc._type_collection === CollectionViewType.Stacking ? - (darkScheme() ? Colors.MEDIUM_GRAY : Colors.DARK_GRAY) - : Cast((props?.renderDepth || 0) > 0 ? Doc.UserDoc().activeCollectionNestedBackground : Doc.UserDoc().activeCollectionBackground, 'string') ?? (darkScheme() ? Colors.BLACK : Colors.MEDIUM_GRAY)); + (Colors.DARK_GRAY) + : Cast((props?.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)"; - default: docColor = docColor || (darkScheme() ? Colors.DARK_GRAY : Colors.WHITE); + default: docColor = docColor || (Colors.WHITE); } return (docColor && !doc) ? DashColor(docColor).fade(0.5).toString() : docColor; } @@ -237,12 +235,12 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps switch (doc?.type) { case DocumentType.COL: return StrCast( - doc?.layout_borderRounding, + doc?.layout_boxShadow, doc?._type_collection === CollectionViewType.Pile ? '4px 4px 10px 2px' : lockedPosition() || doc?._isGroup || docProps?.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) - : `${darkScheme() ? Colors.DARK_GRAY : Colors.MEDIUM_GRAY} ${StrCast(doc.layout_borderRounding, '0.2vw 0.2vw 0.8vw')}` + : `${Colors.MEDIUM_GRAY} ${StrCast(doc.layout_boxShadow, '0.2vw 0.2vw 0.8vw')}` ); case DocumentType.LABEL: @@ -260,14 +258,13 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps } } case StyleProp.PointerEvents: - const isInk = doc && StrCast(Doc.Layout(doc).layout).includes(InkingStroke.name) && !props?.LayoutTemplateString; 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 (docProps?.DocumentView?.().ComponentView?.overridePointerEvents?.() !== undefined) return docProps?.DocumentView?.().ComponentView?.overridePointerEvents?.(); - if (DocumentView.ExploreMode || doc?.layout_unrendered) return isInk ? 'visiblePainted' : 'all'; + if (DocumentView.ExploreMode || doc?.layout_unrendered) return isInk() ? 'visiblePainted' : 'all'; if (props?.contentPointerEvents) return StrCast(props.contentPointerEvents); if (props?.pointerEvents?.() === 'none') return 'none'; if (opacity() === 0) return 'none'; - if (props?.isDocumentActive?.()) return isInk ? 'visiblePainted' : 'all'; + if (props?.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: const lock = () => { @@ -280,22 +277,56 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps } }; const filter = () => { + const dashView = DocumentManager.Instance.getDocumentView(Doc.ActiveDashboard); const showFilterIcon = StrListCast(doc?._childFilters).length || StrListCast(doc?._childFiltersByRanges).length - ? '#18c718bd' //'hasFilter' + ? 'green' // #18c718bd' //'hasFilter' : docProps?.childFilters?.().filter(f => Utils.IsRecursiveFilter(f) && f !== Utils.noDragsDocFilter).length || docProps?.childFiltersByRanges().length ? 'orange' //'inheritsFilter' : undefined; return !showFilterIcon ? null : ( - <div className="styleProvider-filter" onClick={action(() => (SettingsManager.propertiesWidth = 250))}> - <FontAwesomeIcon icon={'filter'} size="lg" style={{ position: 'absolute', top: '1%', right: '1%', cursor: 'pointer', padding: 1, color: showFilterIcon, zIndex: 1 }} /> + <div className="styleProvider-filter"> + <Dropdown + 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.propertiesWidth = 250); + setTimeout(action(() => { + if (PropertiesView.Instance) { + PropertiesView.Instance.CloseAll(); + PropertiesView.Instance.openFilters = true; + } + })); + }) + } + size={Size.XSMALL} + width={15} + height={15} + title={showFilterIcon === 'green' ? + "This view is filtered. Click to view/change filters": + "this view inherits filters from one of its parents"} + color={SettingsManager.userColor} + background={showFilterIcon} + items={[ ...(dashView ? [dashView]: []), ...(props?.docViewPath?.()??[]), ...(props?.DocumentView?[props?.DocumentView?.()]:[])] + .filter(dv => StrListCast(dv.rootDoc.childFilters).length || StrListCast(dv.rootDoc.childRangeFilters).length) + .map(dv => ({ + text: StrCast(dv.rootDoc.title), + val: dv as any, + style: {color:SettingsManager.userColor, background:SettingsManager.userBackgroundColor}, + } as IListItemProps)) } + /> </div> ); }; const audio = () => { const audioAnnoState = (doc: Doc) => StrCast(doc.audioAnnoState, 'stopped'); const audioAnnosCount = (doc: Doc) => StrListCast(doc[Doc.LayoutFieldKey(doc) + '_audioAnnotations']).length; - if (!doc || props?.renderDepth === -1 || (!audioAnnosCount(doc) && audioAnnoState(doc) === 'stopped')) return null; + if (!doc || props?.renderDepth === -1 || !audioAnnosCount(doc)) return null; const audioIconColors: { [key: string]: string } = { recording: 'red', playing: 'green', stopped: 'blue' }; return ( <Tooltip title={<div>{StrListCast(doc[Doc.LayoutFieldKey(doc) + '_audioAnnotations_text']).lastElement()}</div>}> @@ -316,7 +347,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps } export function DashboardToggleButton(doc: Doc, field: string, onIcon: IconProp, offIcon: IconProp, clickFunc?: () => void) { - const color = StrCast(Doc.UserDoc().userColor); + const color = SettingsManager.userColor; return ( <IconButton size={Size.XSMALL} |