From 639be55eaff422e1e982cf41d09edd9e96f014a4 Mon Sep 17 00:00:00 2001 From: yunahi <60233430+yunahi@users.noreply.github.com> Date: Thu, 18 Jun 2020 14:10:34 +0900 Subject: updated menu --- src/client/views/DocumentDecorations.scss | 50 +++-- src/client/views/DocumentDecorations.tsx | 81 +++++++- src/client/views/GestureOverlay.tsx | 21 ++- src/client/views/InkingStroke.tsx | 41 ++++- .../collectionFreeForm/CollectionFreeFormView.tsx | 4 +- .../collectionFreeForm/InkOptionsMenu.tsx | 203 +++++++++++++++++++-- 6 files changed, 362 insertions(+), 38 deletions(-) (limited to 'src/client/views') diff --git a/src/client/views/DocumentDecorations.scss b/src/client/views/DocumentDecorations.scss index 0a96b058b..cf5871bda 100644 --- a/src/client/views/DocumentDecorations.scss +++ b/src/client/views/DocumentDecorations.scss @@ -22,11 +22,20 @@ $linkGap : 3px; } + .documentDecorations-rotation { + pointer-events: auto; + // cursor: grabbing; + cursor: ns-resize; + width: 10px; + height: 10px; + } + .documentDecorations-resizer { pointer-events: auto; background: $alt-accent; opacity: 0.1; } + .documentDecorations-resizer:hover { opacity: 1; } @@ -87,14 +96,17 @@ $linkGap : 3px; background: unset; opacity: 1; } + #documentDecorations-topLeftResizer { - border-left: 2px solid; - border-top: solid 2px; + border-left: 2px solid; + border-top: solid 2px; } + #documentDecorations-bottomRightResizer { - border-right: 2px solid; - border-bottom: solid 2px; + border-right: 2px solid; + border-bottom: solid 2px; } + #documentDecorations-topLeftResizer:hover, #documentDecorations-bottomRightResizer:hover { opacity: 1; @@ -110,14 +122,17 @@ $linkGap : 3px; background: unset; opacity: 1; } + #documentDecorations-topRightResizer { - border-right: 2px solid; - border-top: 2px solid; + border-right: 2px solid; + border-top: 2px solid; } + #documentDecorations-bottomLeftResizer { - border-left: 2px solid; - border-bottom: 2px solid; + border-left: 2px solid; + border-bottom: 2px solid; } + #documentDecorations-topRightResizer:hover, #documentDecorations-bottomLeftResizer:hover { cursor: nesw-resize; @@ -139,10 +154,11 @@ $linkGap : 3px; width: 25px; height: calc(100% + 8px); // 8px for the height of the top resizer bar grid-column-start: 2; - grid-column-end : 2; + grid-column-end: 2; pointer-events: all; padding-left: 5px; } + .documentDecorations-title { opacity: 1; grid-column-start: 3; @@ -150,14 +166,16 @@ $linkGap : 3px; pointer-events: auto; overflow: hidden; text-align: center; - display: flex; + display: flex; border-bottom: solid 1px; - margin-left:10px; + margin-left: 10px; width: calc(100% - 10px); } + .focus-visible { - margin-left:0px; + margin-left: 0px; } + .publishBox { width: 20px; height: 22px; @@ -194,8 +212,9 @@ $linkGap : 3px; width: 8px; height: $MINIMIZED_ICON_SIZE; max-height: 20px; - > svg { - margin:0; + + >svg { + margin: 0; } } @@ -332,7 +351,8 @@ $linkGap : 3px; padding: 2px 12px; list-style: none; - .templateToggle, .chromeToggle { + .templateToggle, + .chromeToggle { text-align: left; } diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 6ca7331d6..8cb0c83ed 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -17,11 +17,13 @@ import { DocumentButtonBar } from './DocumentButtonBar'; import './DocumentDecorations.scss'; import { DocumentView } from "./nodes/DocumentView"; import React = require("react"); -import { Id } from '../../fields/FieldSymbols'; +import { Id, Copy, Update } from '../../fields/FieldSymbols'; import e = require('express'); import { CollectionDockingView } from './collections/CollectionDockingView'; import { SnappingManager } from '../util/SnappingManager'; import { HtmlField } from '../../fields/HtmlField'; +import { InkData, InkField, InkTool } from "../../fields/InkField"; +import { update } from 'serializr'; library.add(faCaretUp); library.add(faObjectGroup); @@ -50,6 +52,10 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> private _resizeUndo?: UndoManager.Batch; private _offX = 0; _offY = 0; // offset from click pt to inner edge of resize border private _snapX = 0; _snapY = 0; // last snapped location of resize border + private _prevX = 0; + private _prevY = 0; + private _centerPoints: { X: number, Y: number }[] = []; + @observable private _accumulatedTitle = ""; @observable private _titleControlString: string = "#title"; @observable private _edtingTitle = false; @@ -237,6 +243,77 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> return false; } + @action + onRotateDown = (e: React.PointerEvent): void => { + setupMoveUpEvents(this, e, this.onRotateMove, this.onRotateUp, (e) => { }); + this._prevX = e.clientX; + this._prevY = e.clientY; + SelectionManager.SelectedDocuments().forEach(action((element: DocumentView) => { + const doc = Document(element.rootDoc); + 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); + this._centerPoints.push({ X: ((right - left) / 2) + left, Y: ((bottom - top) / 2) + bottom }); + } + } + })); + + } + @action + onRotateMove = (e: PointerEvent, down: number[]): boolean => { + // const distance = Math.sqrt((this._prevY - e.clientY) * (this._prevY - e.clientY) + (this._prevX - e.clientX) * (this._prevX - e.clientX)); + const distance = Math.abs(this._prevY - e.clientY); + var angle = 0; + //think of a better condition later... + // if ((down[0] < e.clientX && this._prevY < e.clientY) || (down[0] > e.clientX && this._prevY > e.clientY)) { + if (e.clientY > this._prevY) { + angle = distance * (Math.PI / 180); + // } else if ((down[0] < e.clientX && this._prevY > e.clientY) || (down[0] > e.clientX && this._prevY <= e.clientY)) { + } else if (e.clientY < this._prevY) { + angle = - distance * (Math.PI / 180); + } + this._prevX = e.clientX; + this._prevY = e.clientY; + var index = 0; + SelectionManager.SelectedDocuments().forEach(action((element: DocumentView) => { + const doc = Document(element.rootDoc); + 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 newPoints: { X: number, Y: number }[] = []; + for (var i = 0; i < ink.length; i++) { + const newX = Math.cos(angle) * (ink[i].X - this._centerPoints[index].X) - Math.sin(angle) * (ink[i].Y - this._centerPoints[index].Y) + this._centerPoints[index].X; + const newY = Math.sin(angle) * (ink[i].X - this._centerPoints[index].X) + Math.cos(angle) * (ink[i].Y - this._centerPoints[index].Y) + this._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++; + } + })); + return false; + } + + onRotateUp = (e: PointerEvent) => { + this._centerPoints = []; + } + + + _initialAutoHeight = false; _dragHeights = new Map(); @action @@ -521,6 +598,8 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
{SelectionManager.SelectedDocuments().length === 1 ? DocumentDecorations.DocumentIcon(StrCast(seldoc.props.Document.layout, "...")) : "..."}
+
e.preventDefault()}>
{ const b = this.getBounds(l); return - {InteractionUtils.CreatePolyline(l, b.left, b.top, ActiveInkColor(), ActiveInkWidth(), ActiveInkBezierApprox(), 1, 1, this.InkShape)} + {InteractionUtils.CreatePolyline(l, b.left, b.top, ActiveInkColor(), ActiveInkWidth(), ActiveInkBezierApprox(), ActiveFillColor(), ActiveArrowStart(), ActiveArrowEnd(), ActiveDash(), 1, 1, this.InkShape, "none", false)} ; }), this._points.length <= 1 ? (null) : - {InteractionUtils.CreatePolyline(this._points, B.left, B.top, ActiveInkColor(), ActiveInkWidth(), ActiveInkBezierApprox(), 1, 1, this.InkShape)} + {InteractionUtils.CreatePolyline(this._points, B.left, B.top, ActiveInkColor(), ActiveInkWidth(), ActiveInkBezierApprox(), ActiveFillColor(), ActiveArrowStart(), ActiveArrowEnd(), ActiveDash(), 1, 1, this.InkShape, "none", false)} ] ]; } @@ -901,12 +906,20 @@ Scripting.addGlobal("GestureOverlay", GestureOverlay); Scripting.addGlobal(function setToolglass(tool: any) { runInAction(() => GestureOverlay.Instance.Tool = tool); }); -Scripting.addGlobal(function setPen(width: any, color: any) { +Scripting.addGlobal(function setPen(width: any, color: any, fill: any, arrowStart: any, arrowEnd: any, dash: any) { runInAction(() => { GestureOverlay.Instance.SavedColor = ActiveInkColor(); SetActiveInkColor(color); GestureOverlay.Instance.SavedWidth = ActiveInkWidth(); SetActiveInkWidth(width); + GestureOverlay.Instance.SavedFill = ActiveFillColor(); + SetActiveFillColor(fill); + GestureOverlay.Instance.SavedArrowStart = ActiveArrowStart(); + SetActiveArrowStart(arrowStart); + GestureOverlay.Instance.SavedArrowEnd = ActiveArrowEnd(); + SetActiveArrowStart(arrowEnd); + GestureOverlay.Instance.SavedDash = ActiveDash(); + SetActiveDash(dash); }); }); Scripting.addGlobal(function resetPen() { diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx index a7650163f..324665aea 100644 --- a/src/client/views/InkingStroke.tsx +++ b/src/client/views/InkingStroke.tsx @@ -58,11 +58,13 @@ export class InkingStroke extends ViewBoxBaseComponent 5 ? strokeColor : "transparent", + // strokeColor, (strokeWidth + 15).toString(), - StrCast(this.layoutDoc.strokeBezier, ActiveInkBezierApprox()), scaleX, scaleY, "", this.props.active() ? "visiblestroke" : "none", false); + StrCast(this.layoutDoc.strokeBezier, ActiveInkBezierApprox()), StrCast(this.layoutDoc.fillColor, ActiveFillColor()), StrCast(this.layoutDoc.arrowStart, ActiveArrowStart()), StrCast(this.layoutDoc.arrowEnd, ActiveArrowEnd()), StrCast(this.layoutDoc.dash, ActiveDash()), scaleX, scaleY, "", this.props.active() ? "visiblestroke" : "none", false); + console.log("#" + strokeColor); return ( { ContextMenu.Instance.addItem({ description: "Analyze Stroke", event: this.analyzeStrokes, icon: "paint-brush" }); @@ -93,6 +96,18 @@ export class InkingStroke extends ViewBoxBaseComponent + {/* + + */} + {/* + + + + + */} + {/* + + */} {hpoints} {points} @@ -105,17 +120,33 @@ export class InkingStroke extends ViewBoxBaseComponent) { super(props); @@ -29,18 +43,103 @@ export default class InkOptionsMenu extends AntimodeMenu { this._canFade = false; // don't let the inking menu fade away } + getColors = () => { + return this._palette; + } + + @action + changeArrow = (arrowStart: string, arrowEnd: string) => { + SetActiveArrowStart(arrowStart); + SetActiveArrowEnd(arrowEnd); + } + @action - changeColor = (color: string) => { + changeColor = (color: string, type: string) => { const col: ColorState = { hex: color, hsl: { a: 0, h: 0, s: 0, l: 0, source: "" }, hsv: { a: 0, h: 0, s: 0, v: 0, source: "" }, rgb: { a: 0, r: 0, b: 0, g: 0, source: "" }, oldHue: 0, source: "", }; - SetActiveInkColor(Utils.colorString(col)); + if (type === "color") { + SetActiveInkColor(Utils.colorString(col)); + } else if (type === "fill") { + SetActiveFillColor(Utils.colorString(col)); + } } + @action + editProperties = (value: any, field: string) => { + SelectionManager.SelectedDocuments().forEach(action((element: DocumentView) => { + const doc = Document(element.rootDoc); + if (doc.type === DocumentType.INK) { + switch (field) { + case "width": + doc.strokeWidth = Number(value); + break; + case "color": + doc.color = String(value); + break; + case "fill": + doc.fillColor = String(value); + break; + case "bezier": + // doc.strokeBezier === 300 ? doc.strokeBezier = 0 : doc.strokeBezier = 300; + break; + case "arrowStart": + doc.arrowStart = String(value); + break; + case "arrowEnd": + doc.arrowEnd = String(value); + break; + case "dash": + doc.dash = Number(value); + default: + break; + } + } + })); + } + + @action changeBezier = (e: React.PointerEvent): void => { SetActiveBezierApprox(!ActiveInkBezierApprox() ? "300" : ""); + this.editProperties(0, "bezier"); + } + @action + changeDash = (e: React.PointerEvent): void => { + SetActiveDash(ActiveDash() === "0" ? "2" : "0"); + this.editProperties(ActiveDash(), "dash"); + } + + @computed get arrowPicker() { + var currIcon; + for (var i = 0; i < this._arrowStart.length; i++) { + if (this._arrowStart[i] === ActiveArrowStart() && this._arrowEnd[i] === ActiveArrowEnd()) { + currIcon = this._arrowIcons[i]; + } + } + var arrowPicker = ; + if (this._arrowBtn) { + arrowPicker =
+ {arrowPicker} + {this._arrowStart.map((arrowStart, i) => { + return ; + })} +
; + } + return arrowPicker; } @computed get widthPicker() { @@ -58,7 +157,7 @@ export default class InkOptionsMenu extends AntimodeMenu { return ; @@ -68,6 +167,8 @@ export default class InkOptionsMenu extends AntimodeMenu { return widthPicker; } + + @computed get colorPicker() { var colorPicker = ; @@ -94,6 +195,35 @@ export default class InkOptionsMenu extends AntimodeMenu { return colorPicker; } + @computed get fillPicker() { + var fillPicker = ; + if (this._fillBtn) { + fillPicker =
+ {fillPicker} + {this._palette.map(color => { + return ; + })} + +
; + } + return fillPicker; + } + + + @computed get shapeButtons() { return <> {this._buttons.map((btn, i) => )}, + )} ; } + @computed get shapePicker() { + var currIcon; + if (GestureOverlay.Instance.InkShape === "") { + currIcon = "S"; + } else { + for (var i = 0; i < this._icons.length; i++) { + if (GestureOverlay.Instance.InkShape === this._buttons[i]) { + currIcon = this._icons[i]; + } + } + } + var shapePicker = ; + if (this._shapeBtn) { + shapePicker =
+ {shapePicker} + {this._buttons.map((btn, i) => { + return ; + })} +
; + } + return shapePicker; + } + @computed get bezierButton() { return ; } + @computed get dashButton() { + return ; + } + render() { const buttons = [ , - this.shapeButtons, + this.shapePicker, + // this.shapeButtons, this.bezierButton, this.widthPicker, this.colorPicker, + this.fillPicker, + this.arrowPicker, + this.dashButton ]; return this.getElement(buttons); } -- cgit v1.2.3-70-g09d2