diff options
-rw-r--r-- | src/client/documents/Documents.ts | 8 | ||||
-rw-r--r-- | src/client/views/MainView.tsx | 2 | ||||
-rw-r--r-- | src/client/views/collections/collectionFreeForm/PropertiesView.scss | 55 | ||||
-rw-r--r-- | src/client/views/collections/collectionFreeForm/PropertiesView.tsx | 118 |
4 files changed, 175 insertions, 8 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 32f46bd1c..88c25567e 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -304,10 +304,10 @@ export namespace Docs { [DocumentType.MENUICON, { layout: { view: MenuIconBox, dataField: defaultDataKey }, }], - [DocumentType.RECOMMENDATION, { - layout: { view: RecommendationsBox, dataField: defaultDataKey }, - options: { _width: 200, _height: 200 }, - }], + // [DocumentType.RECOMMENDATION, { + // layout: { view: RecommendationsBox, dataField: defaultDataKey }, + // options: { _width: 200, _height: 200 }, + // }], [DocumentType.WEBCAM, { layout: { view: DashWebRTCVideo, dataField: defaultDataKey } }], diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 0e2362866..8e4851b6e 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -172,7 +172,7 @@ export class MainView extends React.Component { fa.faFillDrip, fa.faLink, fa.faUnlink, fa.faBold, fa.faItalic, fa.faChevronLeft, fa.faUnderline, fa.faStrikethrough, fa.faSuperscript, fa.faSubscript, fa.faIndent, fa.faEyeDropper, fa.faPaintRoller, fa.faBars, fa.faBrush, fa.faShapes, fa.faEllipsisH, fa.faHandPaper, fa.faMap, fa.faUser, faHireAHelper, fa.faDesktop, fa.faTrashRestore, fa.faUsers, fa.faWrench, fa.faCog, fa.faMap, fa.faBellSlash, fa.faExpandAlt, fa.faArchive, fa.faBezierCurve, fa.faCircle, - fa.faLongArrowAltRight, fa.faPenFancy, fa.faAngleDoubleRight, faBuffer, fa.faExpand); + fa.faLongArrowAltRight, fa.faPenFancy, fa.faAngleDoubleRight, faBuffer, fa.faExpand, fa.faUndo); this.initEventListeners(); this.initAuthenticationRouters(); } diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.scss b/src/client/views/collections/collectionFreeForm/PropertiesView.scss index 30598adfb..f44445066 100644 --- a/src/client/views/collections/collectionFreeForm/PropertiesView.scss +++ b/src/client/views/collections/collectionFreeForm/PropertiesView.scss @@ -378,4 +378,59 @@ } } +} + +.inking-button { + + display: flex; + + .inking-button-points { + background-color: #333333; + padding: 7px; + border-radius: 7px; + margin-right: 32px; + width: 32; + height: 32; + padding-top: 9px; + margin-left: 5px; + + &:hover { + background: rgb(131, 131, 131); + transform: scale(1.05); + cursor: pointer; + } + } + + .inking-button-lock { + background-color: #333333; + padding: 7px; + border-radius: 7px; + margin-right: 32px; + width: 32; + height: 32; + padding-top: 9px; + padding-left: 10px; + + &:hover { + background: rgb(131, 131, 131); + transform: scale(1.05); + cursor: pointer; + } + } + + .inking-button-rotate { + background-color: #333333; + padding: 7px; + border-radius: 7px; + width: 32; + height: 32; + padding-top: 9px; + padding-left: 10px; + + &:hover { + background: rgb(131, 131, 131); + transform: scale(1.05); + cursor: pointer; + } + } }
\ No newline at end of file diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx index 57f31ca3d..90a55ed2d 100644 --- a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx +++ b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx @@ -2,7 +2,7 @@ import React = require("react"); import { observer } from "mobx-react"; import "./PropertiesView.scss"; import { observable, action, computed, runInAction } from "mobx"; -import { Doc, Field, DocListCast, WidthSym, HeightSym, AclSym, AclPrivate, AclReadonly, AclAddonly, AclEdit, AclAdmin } from "../../../../fields/Doc"; +import { Doc, Field, DocListCast, WidthSym, HeightSym, AclSym, AclPrivate, AclReadonly, AclAddonly, AclEdit, AclAdmin, Opt } from "../../../../fields/Doc"; import { DocumentView } from "../../nodes/DocumentView"; import { ComputedField } from "../../../../fields/ScriptField"; import { EditableView } from "../../EditableView"; @@ -21,6 +21,11 @@ import SharingManager from "../../../util/SharingManager"; import { DocumentType } from "../../../documents/DocumentTypes"; import FormatShapePane from "./FormatShapePane"; import { SharingPermissions, GetEffectiveAcl } from "../../../../fields/util"; +import { InkField } from "../../../../fields/InkField"; +import { undoBatch } from "../../../util/UndoManager"; +import { ColorState, SketchPicker } from "react-color"; +import AntimodeMenu from "../../AntimodeMenu"; +import "./FormatShapePane.scss"; interface PropertiesViewProps { @@ -349,6 +354,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { SetValue={this.setTitle} />; } + @action setTitle = (value: string) => { if (this.dataDoc) { this.selectedDoc && (this.selectedDoc.title = value); @@ -358,6 +364,112 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { return false; } + + + + + @undoBatch + @action + rotate = (angle: number) => { + const _centerPoints: { X: number, Y: number }[] = []; + if (this.selectedDoc) { + const doc = this.selectedDoc; + if (doc.type === DocumentType.INK && doc.x && doc.y && doc._width && doc._height && doc.data) { + const ink = Cast(doc.data, InkField)?.inkData; + if (ink) { + const xs = ink.map(p => p.X); + const ys = ink.map(p => p.Y); + const left = Math.min(...xs); + const top = Math.min(...ys); + const right = Math.max(...xs); + const bottom = Math.max(...ys); + _centerPoints.push({ X: left, Y: top }); + } + } + + var index = 0; + if (doc.type === DocumentType.INK && doc.x && doc.y && doc._width && doc._height && doc.data) { + doc.rotation = Number(doc.rotation) + Number(angle); + const ink = Cast(doc.data, InkField)?.inkData; + if (ink) { + + const newPoints: { X: number, Y: number }[] = []; + for (var i = 0; i < ink.length; i++) { + const newX = Math.cos(angle) * (ink[i].X - _centerPoints[index].X) - Math.sin(angle) * (ink[i].Y - _centerPoints[index].Y) + _centerPoints[index].X; + const newY = Math.sin(angle) * (ink[i].X - _centerPoints[index].X) + Math.cos(angle) * (ink[i].Y - _centerPoints[index].Y) + _centerPoints[index].Y; + newPoints.push({ X: newX, Y: newY }); + } + doc.data = new InkField(newPoints); + const xs = newPoints.map(p => p.X); + const ys = newPoints.map(p => p.Y); + const left = Math.min(...xs); + const top = Math.min(...ys); + const right = Math.max(...xs); + const bottom = Math.max(...ys); + + doc._height = (bottom - top); + doc._width = (right - left); + } + index++; + } + } + } + + @observable _controlBtn: boolean = false; + @observable _lock: boolean = false; + + @computed + get controlPointsButton() { + return <div className="inking-button"> + <Tooltip title={<><div className="dash-tooltip">{"Edit points"}</div></>}> + <div className="inking-button-points" onPointerDown={action(() => this._controlBtn = !this._controlBtn)} style={{ backgroundColor: this._controlBtn ? "black" : "" }}> + <FontAwesomeIcon icon="bezier-curve" color="white" size="lg" /> + </div> + </Tooltip> + <Tooltip title={<><div className="dash-tooltip">{this._lock ? "Unlock points" : "Lock points"}</div></>}> + <div className="inking-button-lock" onPointerDown={action(() => this._lock = !this._lock)} > + <FontAwesomeIcon icon={this._lock ? "unlock" : "lock"} color="white" size="lg" /> + </div> + </Tooltip> + <Tooltip title={<><div className="dash-tooltip">{"Rotate 90˚"}</div></>}> + <div className="inking-button-rotate" onPointerDown={action(() => this.rotate(Math.PI / 2))}> + <FontAwesomeIcon icon="undo" color="white" size="lg" /> + </div> + </Tooltip> + </div>; + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @computed get appearanceEditor() { return "appearance" }; + + @computed get transformEditor() { return this.controlPointsButton }; + render() { if (!this.selectedDoc) { @@ -416,7 +528,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { </div> </div> {this.openAppearance ? <div className="propertiesView-appearance-content"> - <FormatShapePane /> + {this.appearanceEditor} </div> : null} </div> : null} @@ -429,7 +541,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { </div> </div> {this.openTransform ? <div className="propertiesView-transform-content"> - transform + {this.transformEditor} </div> : null} </div> : null} |