diff options
| author | usodhi <61431818+usodhi@users.noreply.github.com> | 2021-05-13 01:40:40 -0400 |
|---|---|---|
| committer | usodhi <61431818+usodhi@users.noreply.github.com> | 2021-05-13 01:40:40 -0400 |
| commit | fdd5ab800536a8f1dd8acff284bd3a956a4a17ff (patch) | |
| tree | 62ad87dc41cd8fec6e5d7005e616e6f1f44d242a /src/client/views/StyleProvider.tsx | |
| parent | a97cd98786ff5572547430fff6c9a46117423bb1 (diff) | |
| parent | 66f120531a7e86a7a6bfac30e9c966c3baaed99d (diff) | |
merging
Diffstat (limited to 'src/client/views/StyleProvider.tsx')
| -rw-r--r-- | src/client/views/StyleProvider.tsx | 105 |
1 files changed, 45 insertions, 60 deletions
diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index 9102b9fa4..9e61351c4 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -1,7 +1,8 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { IconProp } from '@fortawesome/fontawesome-svg-core'; import 'golden-layout/src/css/goldenlayout-base.css'; import 'golden-layout/src/css/goldenlayout-dark-theme.css'; -import { runInAction } from 'mobx'; +import { runInAction, action } from 'mobx'; import { Doc, Opt, StrListCast } from "../../fields/Doc"; import { List } from '../../fields/List'; import { listSpec } from '../../fields/Schema'; @@ -9,16 +10,16 @@ import { BoolCast, Cast, NumCast, StrCast } from "../../fields/Types"; import { DocumentType } from '../documents/DocumentTypes'; import { CurrentUserUtils } from '../util/CurrentUserUtils'; import { SnappingManager } from '../util/SnappingManager'; -import { UndoManager } from '../util/UndoManager'; +import { UndoManager, undoBatch } from '../util/UndoManager'; import { CollectionViewType } from './collections/CollectionView'; +import "./collections/TreeView.scss"; import { MainView } from './MainView'; import { DocumentViewProps } from "./nodes/DocumentView"; -import "./StyleProvider.scss"; -import "./collections/TreeView.scss"; +import { FieldViewProps } from './nodes/FieldView'; import "./nodes/FilterBox.scss"; +import "./StyleProvider.scss"; import React = require("react"); import Color = require('color'); -import { FieldViewProps } from './nodes/FieldView'; export enum StyleLayers { Background = "background" @@ -41,6 +42,9 @@ export enum StyleProp { HeaderMargin = "headerMargin", // margin at top of documentview, typically for displaying a title -- doc contents will start below that TitleHeight = "titleHeight", // Height of Title area ShowTitle = "showTitle", // whether to display a title on a Document (optional :hover suffix) + JitterRotation = "jitterRotation", // whether documents should be randomly rotated + BorderPath = "customBorder", // border path for document view + FontSize = "fontSize", // size of text font } function darkScheme() { return BoolCast(CurrentUserUtils.ActiveDashboard?.darkScheme); } @@ -60,7 +64,10 @@ export function testDocProps(toBeDetermined: any): toBeDetermined is DocumentVie return (toBeDetermined?.isContentActive) ? toBeDetermined : undefined; } -// +export function wavyBorderPath(pw: number, ph: number, inset: number = 0.05) { + return `M ${pw * .5} ${ph * inset} C ${pw * .6} ${ph * inset} ${pw * (1 - 2 * inset)} 0 ${pw * (1 - inset)} ${ph * inset} C ${pw} ${ph * (2 * inset)} ${pw * (1 - inset)} ${ph * .25} ${pw * (1 - inset)} ${ph * .3} C ${pw * (1 - inset)} ${ph * .4} ${pw} ${ph * (1 - 2 * inset)} ${pw * (1 - inset)} ${ph * (1 - inset)} C ${pw * (1 - 2 * inset)} ${ph} ${pw * .6} ${ph * (1 - inset)} ${pw * .5} ${ph * (1 - inset)} C ${pw * .3} ${ph * (1 - inset)} ${pw * (2 * inset)} ${ph} ${pw * inset} ${ph * (1 - inset)} C 0 ${ph * (1 - 2 * inset)} ${pw * inset} ${ph * .8} ${pw * inset} ${ph * .75} C ${pw * inset} ${ph * .7} 0 ${ph * (2 * inset)} ${pw * inset} ${ph * inset} C ${pw * (2 * inset)} 0 ${pw * .25} ${ph * inset} ${pw * .5} ${ph * inset}`; +} + // 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<DocumentViewProps>, property: string): any { @@ -70,36 +77,43 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps const isAnchor = property.includes(":anchor"); const isAnnotated = property.includes(":annotated"); const isOpen = property.includes(":open"); + const fieldKey = (props as any)?.fieldKey ? (props as any).fieldKey + "-" : isCaption ? "caption-" : ""; + const comicStyle = () => doc && !Doc.IsSystem(doc) && Doc.UserDoc().renderStyle === "comic"; const isBackground = () => StrListCast(doc?._layerTags).includes(StyleLayers.Background); const backgroundCol = () => props?.styleProvider?.(doc, props, StyleProp.BackgroundColor); const opacity = () => props?.styleProvider?.(doc, props, StyleProp.Opacity); const showTitle = () => props?.styleProvider?.(doc, props, StyleProp.ShowTitle); - + const random = (min: number, max: number, x: number, y: number) => /* min should not be equal to max */ min + ((Math.abs(x * y) * 9301 + 49297) % 233280 / 233280) * (max - min); switch (property.split(":")[0]) { case StyleProp.TreeViewIcon: return Doc.toIcon(doc, isOpen); case StyleProp.DocContents: return undefined; case StyleProp.WidgetColor: return isAnnotated ? "lightBlue" : darkScheme() ? "lightgrey" : "dimgrey"; case StyleProp.Opacity: return Cast(doc?._opacity, "number", Cast(doc?.opacity, "number", null)); case StyleProp.HideLinkButton: return props?.hideLinkButton || (!selected && (doc?.isLinkButton || doc?.hideLinkButton)); + case StyleProp.FontSize: return StrCast(doc?.[fieldKey + "fontSize"]); case StyleProp.ShowTitle: return doc && !doc.presentationTargetDoc && StrCast(doc._showTitle, !Doc.IsSystem(doc) && doc.type === DocumentType.RTF ? (doc.author === Doc.CurrentUserEmail ? StrCast(Doc.UserDoc().showTitle) : "author;creationDate") : "") || ""; case StyleProp.Color: - if (isCaption) return "white"; - const backColor = backgroundCol() || "black"; - const col = Color(backColor).rgb(); + const docColor: Opt<string> = StrCast(doc?.[fieldKey + "color"], StrCast(doc?._color)); + if (docColor) return docColor; + const backColor = backgroundCol();// || (darkScheme() ? "black" : "white"); + if (!backColor) return undefined; + const nonAlphaColor = backColor.startsWith("#") ? (backColor as string).substring(0, 7) : + backColor.startsWith("rgba") ? backColor.replace(/,.[^,]*\)/, ")").replace("rgba", "rgb") : backColor + const col = Color(nonAlphaColor).rgb(); const colsum = (col.red() + col.green() + col.blue()); if (colsum / col.alpha() > 400 || col.alpha() < 0.25) return "black"; return "white"; case StyleProp.Hidden: return BoolCast(doc?._hidden); - case StyleProp.BorderRounding: return StrCast(doc?._borderRounding); + case StyleProp.BorderRounding: return StrCast(doc?.[fieldKey + "borderRounding"]); case StyleProp.TitleHeight: return 15; + case StyleProp.BorderPath: return comicStyle() && props?.renderDepth ? { path: wavyBorderPath(props?.PanelWidth?.() || 0, props?.PanelHeight?.() || 0), fill: wavyBorderPath(props?.PanelWidth?.() || 0, props?.PanelHeight?.() || 0, .08), width: 3 } : { path: undefined, width: 0 }; + case StyleProp.JitterRotation: return comicStyle() ? random(-1, 1, NumCast(doc?.x), NumCast(doc?.y)) * ((props?.PanelWidth() || 0) > (props?.PanelHeight() || 0) ? 5 : 10) : 0; case StyleProp.HeaderMargin: return ([CollectionViewType.Stacking, CollectionViewType.Masonry].includes(doc?._viewType as any) || doc?.type === DocumentType.RTF) && showTitle() && !StrCast(doc?.showTitle).includes(":hover") ? 15 : 0; case StyleProp.BackgroundColor: { - if (isCaption) return "rgba(0,0,0 ,0.4)"; - if (Doc.UserDoc().renderStyle === "comic") return "transparent"; - let docColor: Opt<string> = StrCast(doc?._backgroundColor); + let docColor: Opt<string> = StrCast(doc?.[fieldKey + "backgroundColor"], StrCast(doc?._backgroundColor, isCaption ? "rgba(0,0,0,0.4)" : "")); if (MainView.Instance.LastButton === doc) return darkScheme() ? "dimgrey" : "lightgrey"; switch (doc?.type) { case DocumentType.PRESELEMENT: docColor = docColor || (darkScheme() ? "" : ""); break; @@ -114,6 +128,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps case DocumentType.BUTTON: docColor = docColor || (darkScheme() ? "#2d2d2d" : "lightgray"); break; case DocumentType.LINKANCHOR: docColor = isAnchor ? "lightblue" : "transparent"; break; case DocumentType.LINK: docColor = docColor || "transparent"; break; + case DocumentType.IMG: case DocumentType.WEB: case DocumentType.PDF: case DocumentType.SCREENSHOT: @@ -130,7 +145,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps Doc.UserDoc().activeCollectionBackground)); break; //if (doc._viewType !== CollectionViewType.Freeform && doc._viewType !== CollectionViewType.Time) return "rgb(62,62,62)"; - default: docColor = darkScheme() ? "black" : "white"; break; + default: docColor = docColor || (darkScheme() ? "black" : "white"); break; } if (docColor && (!doc || props?.layerProvider?.(doc) === false)) docColor = Color(docColor.toLowerCase()).fade(0.5).toString(); return docColor; @@ -177,60 +192,30 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps } } - -function toggleHidden(e: React.MouseEvent, doc: Doc) { - UndoManager.RunInBatch(() => runInAction(() => { - e.stopPropagation(); - doc.hidden = doc.hidden ? undefined : true; - }), "toggleHidden"); -} - -function toggleLock(e: React.MouseEvent, doc: Doc) { - UndoManager.RunInBatch(() => runInAction(() => { - e.stopPropagation(); - doc.lockedPosition = doc.lockedPosition ? undefined : true; - }), "toggleHidden"); +export function DashboardToggleButton(doc: Doc, field: string, onIcon: IconProp, offIcon: IconProp, clickFunc?: () => void) { + return <div className={`styleProvider-treeView-icon${doc[field] ? "-active" : ""}`} + onClick={undoBatch(action((e: React.MouseEvent) => { + e.stopPropagation(); + clickFunc ? clickFunc() : (doc[field] = doc[field] ? undefined : true); + }))}> + <FontAwesomeIcon icon={(doc[field] ? onIcon as any : offIcon) as IconProp} size="sm" /> + </div>; } - /** * add lock and hide button decorations for the "Dashboards" flyout TreeView */ export function DashboardStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps | DocumentViewProps>, property: string) { - switch (property.split(":")[0]) { - case StyleProp.Decorations: - if (doc) { - const hidden = doc.hidden; - const locked = doc.lockedPosition; - return doc._viewType === CollectionViewType.Docking || (Doc.IsSystem(doc) && Doc.UserDoc().noviceMode) ? (null) : - <> - <div className={`styleProvider-treeView-hide${hidden ? "-active" : ""}`} onClick={(e) => toggleHidden(e, doc)}> - <FontAwesomeIcon icon={hidden ? "eye-slash" : "eye"} size="sm" /> - </div> - <div className={`styleProvider-treeView-lock${locked ? "-active" : ""}`} onClick={(e) => toggleLock(e, doc)}> - <FontAwesomeIcon icon={locked ? "lock" : "unlock"} size="sm" /> - </div> - </>; - } - default: return DefaultStyleProvider(doc, props, property); + if (doc && property.split(":")[0] === StyleProp.Decorations) { + return doc._viewType === CollectionViewType.Docking ? (null) : + <> + {DashboardToggleButton(doc, "hidden", "eye-slash", "eye")} + {DashboardToggleButton(doc, "lockedPosition", "lock", "unlock")} + </>; } + return DefaultStyleProvider(doc, props, property); } -function changeFilterBool(e: any, doc: Doc) { - UndoManager.RunInBatch(() => runInAction(() => { - //e.stopPropagation(); - //doc.lockedPosition = doc.lockedPosition ? undefined : true; - }), "changeFilterBool"); -} - -function closeFilter(e: React.MouseEvent, doc: Doc) { - UndoManager.RunInBatch(() => runInAction(() => { - e.stopPropagation(); - //doc.lockedPosition = doc.lockedPosition ? undefined : true; - }), "closeFilter"); -} - - // // a preliminary semantic-"layering/grouping" mechanism for determining interactive properties of documents // currently, the provider tests whether the docuemnt's layer field matches the activeLayer field of the tab. |
