diff options
author | vkalev <vjk1883@gmail.com> | 2021-09-03 13:18:46 -0400 |
---|---|---|
committer | vkalev <vjk1883@gmail.com> | 2021-09-03 13:18:46 -0400 |
commit | 15bc374105eb7c55493d9ca6c2b12f9bf22735c9 (patch) | |
tree | f08ffe9ef4f7155f026e0a5362033990ff8b13f7 /src | |
parent | 8ab10535c0fa07247f88902089ffc23f56a22d7d (diff) |
adding ComponentDecorations
Diffstat (limited to 'src')
-rw-r--r-- | src/client/views/ComponentDecorations.scss | 0 | ||||
-rw-r--r-- | src/client/views/ComponentDecorations.tsx | 14 | ||||
-rw-r--r-- | src/client/views/DocumentDecorations.scss | 631 | ||||
-rw-r--r-- | src/client/views/DocumentDecorations.tsx | 19 | ||||
-rw-r--r-- | src/client/views/InkStroke.scss | 11 | ||||
-rw-r--r-- | src/client/views/InkingStroke.tsx | 18 | ||||
-rw-r--r-- | src/client/views/MainView.tsx | 2 | ||||
-rw-r--r-- | src/client/views/nodes/DocumentView.tsx | 2 |
8 files changed, 354 insertions, 343 deletions
diff --git a/src/client/views/ComponentDecorations.scss b/src/client/views/ComponentDecorations.scss new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/src/client/views/ComponentDecorations.scss diff --git a/src/client/views/ComponentDecorations.tsx b/src/client/views/ComponentDecorations.tsx new file mode 100644 index 000000000..66f81fe4f --- /dev/null +++ b/src/client/views/ComponentDecorations.tsx @@ -0,0 +1,14 @@ +import { observer } from "mobx-react"; +import { SelectionManager } from "../util/SelectionManager"; +import './ComponentDecorations.scss'; +import React = require("react"); + +@observer +export class ComponentDecorations extends React.Component { + static Instance: ComponentDecorations; + + render() { + const seldoc = SelectionManager.Views().lastElement(); + return seldoc?.ComponentView?.componentUI?.() ?? (null); + } +}
\ No newline at end of file diff --git a/src/client/views/DocumentDecorations.scss b/src/client/views/DocumentDecorations.scss index 68e0d12d4..2e7142a8e 100644 --- a/src/client/views/DocumentDecorations.scss +++ b/src/client/views/DocumentDecorations.scss @@ -1,419 +1,408 @@ @import "global/globalCssVariables"; -$linkGap : 3px; +$linkGap: 3px; .documentDecorations { - position: absolute; - z-index: 2000; -} -.documentDecorations-inkstroke { - position: absolute; - overflow: visible; - pointer-events: none; - - svg:not(:root) { - overflow: visible !important; - } + position: absolute; + z-index: 2000; } .documentDecorations-container { - z-index: $docDecorations-zindex; + z-index: $docDecorations-zindex; + position: absolute; + top: 0; + left: 0; + display: grid; + grid-template-rows: 20px 8px 1fr 8px; + grid-template-columns: 8px 16px 1fr 8px 8px; + pointer-events: none; + + .documentDecorations-centerCont { + grid-column: 3; + background: none; + } + + .documentDecorations-selectorButton { + pointer-events: auto; + height: 15px; + width: 15px; + left: -20px; + top: 20px; + display: inline-block; position: absolute; - top: 0; - left: 0; - display: grid; - grid-template-rows: 20px 8px 1fr 8px; - grid-template-columns: 8px 16px 1fr 8px 8px; - pointer-events: none; - - .documentDecorations-centerCont { - grid-column: 3; - background: none; - } + opacity: 0.5; + } - .documentDecorations-selectorButton { - pointer-events: auto; - height: 15px; - width: 15px; - left: -20px; - top: 20px; - display: inline-block; - position: absolute; - opacity: 0.5; - } + .documentDecorations-radius { + pointer-events: auto; + opacity: 1; + transform: translate(10px, 10px); + grid-row: 4; + } - .documentDecorations-radius { - pointer-events: auto; - opacity: 1; - transform: translate(10px, 10px); - grid-row: 4; + .documentDecorations-topLeftResizer, + .documentDecorations-topRightResizer, + .documentDecorations-bottomLeftResizer, + .documentDecorations-bottomRightResizer, + .documentDecorations-leftResizer, + .documentDecorations-topResizer, + .documentDecorations-bottomResizer, + .documentDecorations-rightResizer { + pointer-events: auto; + background: $medium-gray; + opacity: 0.1; + &:hover { + opacity: 1; } + } - .documentDecorations-topLeftResizer, - .documentDecorations-topRightResizer, - .documentDecorations-bottomLeftResizer, - .documentDecorations-bottomRightResizer, - .documentDecorations-leftResizer, - .documentDecorations-topResizer, - .documentDecorations-bottomResizer, - .documentDecorations-rightResizer { - pointer-events: auto; - background: $medium-gray; - opacity: 0.1; - &:hover { - opacity: 1; - } - } + .documentDecorations-topLeftResizer, + .documentDecorations-leftResizer, + .documentDecorations-bottomLeftResizer { + grid-column: 1; + } - .documentDecorations-topLeftResizer, - .documentDecorations-leftResizer, - .documentDecorations-bottomLeftResizer { - grid-column: 1 - } + .documentDecorations-topResizer, + .documentDecorations-bottomResizer { + grid-column-start: 2; + grid-column-end: 5; + } - .documentDecorations-topResizer, - .documentDecorations-bottomResizer { - grid-column-start: 2; - grid-column-end: 5; - } + .documentDecorations-bottomRightResizer, + .documentDecorations-topRightResizer, + .documentDecorations-rightResizer { + grid-column-start: 5; + grid-column-end: 7; + } - .documentDecorations-bottomRightResizer, - .documentDecorations-topRightResizer, - .documentDecorations-rightResizer { - grid-column-start: 5; - grid-column-end: 7; - } + .documentDecorations-rotation, + .documentDecorations-borderRadius { + grid-column: 5; + grid-row: 4; + border-radius: 100%; + background: black; + height: 8; + right: -12; + top: 12; + position: relative; + pointer-events: all; + cursor: nwse-resize; - .documentDecorations-rotation, - .documentDecorations-borderRadius { - grid-column: 5; - grid-row: 4; - border-radius: 100%; - background: black; - height: 8; - right: -12; - top: 12; - position: relative; - pointer-events: all; - cursor: nwse-resize; - - .borderRadiusTooltip { - width: 10px; - height: 10px; - position: absolute; - } + .borderRadiusTooltip { + width: 10px; + height: 10px; + position: absolute; } - .documentDecorations-rotation { - background: transparent; - right: -15; - } - + } + .documentDecorations-rotation { + background: transparent; + right: -15; + } - .documentDecorations-topLeftResizer, - .documentDecorations-bottomRightResizer { - cursor: nwse-resize; - background: unset; - opacity: 1; - } + .documentDecorations-topLeftResizer, + .documentDecorations-bottomRightResizer { + cursor: nwse-resize; + background: unset; + opacity: 1; + } - .documentDecorations-topLeftResizer { - border-left: 2px solid; - border-top: solid 2px; - } + .documentDecorations-topLeftResizer { + border-left: 2px solid; + border-top: solid 2px; + } - .documentDecorations-bottomRightResizer { - border-right: 2px solid; - border-bottom: solid 2px; - } + .documentDecorations-bottomRightResizer { + border-right: 2px solid; + border-bottom: solid 2px; + } - .documentDecorations-topLeftResizer:hover, - .documentDecorations-bottomRightResizer:hover { - opacity: 1; - } + .documentDecorations-topLeftResizer:hover, + .documentDecorations-bottomRightResizer:hover { + opacity: 1; + } - .documentDecorations-bottomRightResizer { - grid-row: 4; - } + .documentDecorations-bottomRightResizer { + grid-row: 4; + } - .documentDecorations-topRightResizer, - .documentDecorations-bottomLeftResizer { - cursor: nesw-resize; - background: unset; - opacity: 1; - } + .documentDecorations-topRightResizer, + .documentDecorations-bottomLeftResizer { + cursor: nesw-resize; + background: unset; + opacity: 1; + } - .documentDecorations-topRightResizer { - border-right: 2px solid; - border-top: 2px solid; - } + .documentDecorations-topRightResizer { + border-right: 2px solid; + border-top: 2px solid; + } - .documentDecorations-bottomLeftResizer { - border-left: 2px solid; - border-bottom: 2px solid; - } + .documentDecorations-bottomLeftResizer { + border-left: 2px solid; + border-bottom: 2px solid; + } - .documentDecorations-topRightResizer:hover, - .documentDecorations-bottomLeftResizer:hover { - cursor: nesw-resize; - background: black; - opacity: 1; - } + .documentDecorations-topRightResizer:hover, + .documentDecorations-bottomLeftResizer:hover { + cursor: nesw-resize; + background: black; + opacity: 1; + } - .documentDecorations-topResizer, - .documentDecorations-bottomResizer { - cursor: ns-resize; - } + .documentDecorations-topResizer, + .documentDecorations-bottomResizer { + cursor: ns-resize; + } - .documentDecorations-leftResizer, - .documentDecorations-rightResizer { - cursor: ew-resize; - } + .documentDecorations-leftResizer, + .documentDecorations-rightResizer { + cursor: ew-resize; + } - .documentDecorations-contextMenu { - width: 25px; - height: calc(100% + 8px); // 8px for the height of the top resizer bar - grid-column-start: 2; - grid-column-end: 2; - pointer-events: all; - padding-left: 5px; - cursor: pointer; - } + .documentDecorations-contextMenu { + width: 25px; + height: calc(100% + 8px); // 8px for the height of the top resizer bar + grid-column-start: 2; + grid-column-end: 2; + pointer-events: all; + padding-left: 5px; + cursor: pointer; + } - .documentDecorations-titleBackground { - background: #ffffffcf; - border-radius: 8px; - width: 100%; - height: 100%; - position: absolute; - } + .documentDecorations-titleBackground { + background: #ffffffcf; + border-radius: 8px; + width: 100%; + height: 100%; + position: absolute; + } - .documentDecorations-title { - opacity: 1; - grid-column-start: 2; - grid-column-end: 4; - pointer-events: auto; - overflow: hidden; - text-align: center; - display: flex; - margin-left: 5px; - height: 22px; - position: absolute; - .documentDecorations-titleSpan { - width: 100%; - border-radius: 8px; - background: #ffffffcf; - position: absolute; - display: inline-block; - cursor: move; - } + .documentDecorations-title { + opacity: 1; + grid-column-start: 2; + grid-column-end: 4; + pointer-events: auto; + overflow: hidden; + text-align: center; + display: flex; + margin-left: 5px; + height: 22px; + position: absolute; + .documentDecorations-titleSpan { + width: 100%; + border-radius: 8px; + background: #ffffffcf; + position: absolute; + display: inline-block; + cursor: move; } + } - .focus-visible { - margin-left: 0px; - } + .focus-visible { + margin-left: 0px; + } } - .documentDecorations-iconifyButton { - opacity: 1; - grid-column-start: 4; - grid-column-end: 4; - pointer-events: all; - right: 0; - cursor: pointer; - position: absolute; - width: 20px; + opacity: 1; + grid-column-start: 4; + grid-column-end: 4; + pointer-events: all; + right: 0; + cursor: pointer; + position: absolute; + width: 20px; } .documentDecorations-openButton { - display: flex; - align-items: center; - opacity: 1; - grid-column-start: 5; - grid-column-end: 5; - pointer-events: all; - cursor: pointer; + display: flex; + align-items: center; + opacity: 1; + grid-column-start: 5; + grid-column-end: 5; + pointer-events: all; + cursor: pointer; } .documentDecorations-closeButton { - display: flex; - align-items: center; - opacity: 1; - grid-column-start: 1; - grid-column-end: 3; - pointer-events: all; - cursor: pointer; - - >svg { - margin: 0; - } + display: flex; + align-items: center; + opacity: 1; + grid-column-start: 1; + grid-column-end: 3; + pointer-events: all; + cursor: pointer; + + > svg { + margin: 0; + } } .documentDecorations-background { - background: lightblue; - position: absolute; - opacity: 0.1; + background: lightblue; + position: absolute; + opacity: 0.1; } .linkFlyout { - grid-column: 2/4; + grid-column: 2/4; } .linkButton-empty:hover { - background: $medium-gray; - transform: scale(1.05); - cursor: pointer; + background: $medium-gray; + transform: scale(1.05); + cursor: pointer; } .linkButton-nonempty:hover { - background: $medium-gray; - transform: scale(1.05); - cursor: pointer; + background: $medium-gray; + transform: scale(1.05); + cursor: pointer; } .link-button-container { - border-radius: 10px; - width: max-content; - height: auto; - display: flex; - flex-direction: row; - z-index: 998; - position: absolute; - justify-content: center; - align-items: center; - gap: 5px; - background: $medium-gray; + border-radius: 10px; + width: max-content; + height: auto; + display: flex; + flex-direction: row; + z-index: 998; + position: absolute; + justify-content: center; + align-items: center; + gap: 5px; + background: $medium-gray; } .linkButtonWrapper { - pointer-events: auto; - padding-right: 5px; - width: 25px; + pointer-events: auto; + padding-right: 5px; + width: 25px; } .linkButton-linker { - height: 20px; - width: 20px; - text-align: center; - border-radius: 50%; - pointer-events: auto; - color: $dark-gray; - border: $dark-gray 1px solid; + height: 20px; + width: 20px; + text-align: center; + border-radius: 50%; + pointer-events: auto; + color: $dark-gray; + border: $dark-gray 1px solid; } .linkButton-linker:hover { - cursor: pointer; - transform: scale(1.05); + cursor: pointer; + transform: scale(1.05); } .linkButton-empty, .linkButton-nonempty { - height: 20px; - width: 20px; - border-radius: 50%; - opacity: 0.9; - pointer-events: auto; - background-color: $dark-gray; - color: $white; - text-transform: uppercase; - letter-spacing: 2px; - font-size: 75%; - transition: transform 0.2s; - text-align: center; - display: flex; - justify-content: center; - align-items: center; - - &:hover { - background: $medium-gray; - transform: scale(1.05); - cursor: pointer; - } + height: 20px; + width: 20px; + border-radius: 50%; + opacity: 0.9; + pointer-events: auto; + background-color: $dark-gray; + color: $white; + text-transform: uppercase; + letter-spacing: 2px; + font-size: 75%; + transition: transform 0.2s; + text-align: center; + display: flex; + justify-content: center; + align-items: center; + + &:hover { + background: $medium-gray; + transform: scale(1.05); + cursor: pointer; + } } .templating-menu { - position: absolute; - pointer-events: auto; - text-transform: uppercase; - letter-spacing: 2px; - font-size: 75%; - transition: transform 0.2s; - text-align: center; - display: flex; - justify-content: center; - align-items: center; + position: absolute; + pointer-events: auto; + text-transform: uppercase; + letter-spacing: 2px; + font-size: 75%; + transition: transform 0.2s; + text-align: center; + display: flex; + justify-content: center; + align-items: center; } .documentdecorations-icon { - margin: 0px; + margin: 0px; } .templating-button, .docDecs-tagButton { - width: 20px; - height: 20px; - border-radius: 50%; - opacity: 0.9; - font-size: 14; - background-color: $dark-gray; - color: $white; - text-align: center; - cursor: pointer; - - &:hover { - background: $medium-gray; - transform: scale(1.05); - } + width: 20px; + height: 20px; + border-radius: 50%; + opacity: 0.9; + font-size: 14; + background-color: $dark-gray; + color: $white; + text-align: center; + cursor: pointer; + + &:hover { + background: $medium-gray; + transform: scale(1.05); + } } .documentDecorations-darkScheme { - background: dimgray; + background: dimgray; } #template-list { - position: absolute; - top: 25px; - left: 0px; - width: max-content; - font-family: $sans-serif; - font-size: 12px; - background-color: $light-gray; - padding: 2px 12px; - list-style: none; - - .templateToggle, - .chromeToggle { - text-align: left; - } + position: absolute; + top: 25px; + left: 0px; + width: max-content; + font-family: $sans-serif; + font-size: 12px; + background-color: $light-gray; + padding: 2px 12px; + list-style: none; + + .templateToggle, + .chromeToggle { + text-align: left; + } - input { - margin-right: 10px; - } + input { + margin-right: 10px; + } } @-moz-keyframes spin { - 100% { - -moz-transform: rotate(360deg); - } + 100% { + -moz-transform: rotate(360deg); + } } @-webkit-keyframes spin { - 100% { - -webkit-transform: rotate(360deg); - } + 100% { + -webkit-transform: rotate(360deg); + } } @keyframes spin { - 100% { - -webkit-transform: rotate(360deg); - transform: rotate(360deg); - } + 100% { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); + } } @keyframes shadow-pulse { - 0% { - box-shadow: 0 0 0 0px rgba(0, 0, 0, 0.8); - } + 0% { + box-shadow: 0 0 0 0px rgba(0, 0, 0, 0.8); + } - 100% { - box-shadow: 0 0 0 10px rgba(0, 255, 0, 0); - } -}
\ No newline at end of file + 100% { + box-shadow: 0 0 0 10px rgba(0, 255, 0, 0); + } +} diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 3ffbb2904..2348c897b 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -457,24 +457,6 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number, P bounds.b = Math.max(bounds.y, Math.max(topBounds, Math.min(window.innerHeight, bounds.b + this._resizeBorderWidth / 2 + this._linkBoxHeight) - this._resizeBorderWidth / 2 - this._linkBoxHeight)); const useRotation = seldoc.rootDoc.type === DocumentType.INK; - const screenData = seldoc.ComponentView?.screenStrokeData?.(); - let selectedLine = (null); - if (screenData) { - const inkDoc = seldoc.props.Document; - const overlayWidth = 10; - selectedLine = <div className="documentDecorations-inkstroke" style={{ - width: (bounds.r - bounds.x) + "px", - height: (bounds.b - bounds.y) + "px", - left: bounds.x, - top: bounds.y, - }} > - {InteractionUtils.CreatePolyline(screenData.screenPts, screenData.screenLeft, screenData.screenTop, Colors.MEDIUM_BLUE, overlayWidth, overlayWidth, - StrCast(inkDoc.strokeBezier), StrCast(inkDoc.fillColor, "none"), - StrCast(inkDoc.strokeStartMarker), StrCast(inkDoc.strokeEndMarker), - StrCast(inkDoc.strokeDash), 1, 1, "", "none", 1.0, false)} - - </div> - } return (<div className="documentDecorations" style={{ background: CurrentUserUtils.ActiveDashboard?.darkScheme ? "dimgray" : "" }} > <div className="documentDecorations-background" style={{ @@ -516,7 +498,6 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number, P </> } </div > - {selectedLine} {seldoc?.Document.type === DocumentType.FONTICON ? (null) : <div className="link-button-container" key="links" style={{ left: bounds.x - this._resizeBorderWidth / 2 + 10, top: bounds.b + this._resizeBorderWidth / 2 }}> <DocumentButtonBar views={SelectionManager.Views} /> </div>} diff --git a/src/client/views/InkStroke.scss b/src/client/views/InkStroke.scss index 812a79bd5..8edefa07b 100644 --- a/src/client/views/InkStroke.scss +++ b/src/client/views/InkStroke.scss @@ -1,3 +1,14 @@ +.inkstroke-UI { + // transform-origin: top left; + position: absolute; + overflow: visible; + pointer-events: none; + + svg:not(:root) { + overflow: visible !important; + } +} + .inkStroke { mix-blend-mode: multiply; stroke-linejoin: round; diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx index 297b3333c..41fbe0d55 100644 --- a/src/client/views/InkingStroke.tsx +++ b/src/client/views/InkingStroke.tsx @@ -114,7 +114,7 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocume }; } - screenStrokeData = () => { + componentUI = () => { const { inkData, inkScaleX, inkScaleY, inkStrokeWidth } = this.inkScaledData(); const screenInkWidth = this.props.ScreenToLocalTransform().inverse().transformDirection(inkStrokeWidth, inkStrokeWidth); @@ -122,7 +122,21 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocume const screenTop = Math.min(...screenPts.map(p => p.Y)) - screenInkWidth[0] / 2; const screenLeft = Math.min(...screenPts.map(p => p.X)) - screenInkWidth[0] / 2; - return { screenPts, screenLeft, screenTop }; + const inkDoc = this.props.Document; + + const overlayWidth = 5; + return <div className="inkstroke-UI" style={{ + // width: (bounds.r - bounds.x) + "px", + // height: (bounds.b - bounds.y) + "px", + left: screenLeft, + top: screenTop, + }} > + {InteractionUtils.CreatePolyline(screenPts, screenLeft, screenTop, Colors.MEDIUM_BLUE, overlayWidth, overlayWidth, + StrCast(inkDoc.strokeBezier), StrCast(inkDoc.fillColor, "none"), + StrCast(inkDoc.strokeStartMarker), StrCast(inkDoc.strokeEndMarker), + StrCast(inkDoc.strokeDash), 1, 1, "", "none", 1.0, false)} + + </div> } render() { diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 1ce363b0a..b81459075 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -39,6 +39,7 @@ import { CollectionViewType } from './collections/CollectionView'; import { ContextMenu } from './ContextMenu'; import { DictationOverlay } from './DictationOverlay'; import { DocumentDecorations } from './DocumentDecorations'; +import { ComponentDecorations } from './ComponentDecorations'; import { GestureOverlay } from './GestureOverlay'; import { MENU_PANEL_WIDTH, SEARCH_PANEL_HEIGHT } from './global/globalCssVariables.scss'; import { KeyManager } from './GlobalKeyHandler'; @@ -594,6 +595,7 @@ export class MainView extends React.Component { <GroupManager /> <GoogleAuthenticationManager /> <DocumentDecorations PanelWidth={this._windowWidth} PanelHeight={this._windowHeight} boundsLeft={this.leftOffset} boundsTop={this.topOffset} /> + <ComponentDecorations /> {this.search} {LinkDescriptionPopup.descriptionPopup ? <LinkDescriptionPopup /> : null} {DocumentLinksButton.LinkEditorDocView ? <LinkMenu docView={DocumentLinksButton.LinkEditorDocView} changeFlyout={emptyFunction} /> : (null)} diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 3587c1d2a..4e6ed40d1 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -88,7 +88,7 @@ export interface DocComponentView { setKeyFrameEditing?: (set: boolean) => void; // whether the document is in keyframe editing mode (if it is, then all hidden documents that are not active at the keyframe time will still be shown) playFrom?: (time: number, endTime?: number) => void; setFocus?: () => void; - screenStrokeData?: () => { screenPts: { X: number, Y: number }[], screenTop: number, screenLeft: number }; + componentUI?: () => JSX.Element; } export interface DocumentViewSharedProps { renderDepth: number; |