From d58195a0470b3882d6b43b18f1f4ab7a373a671f Mon Sep 17 00:00:00 2001 From: Stanley Yip Date: Sat, 12 Oct 2019 17:02:31 -0400 Subject: marquee now relies on pdf-style menu. pdf-style menu is now componentized so that other things can use it --- src/client/views/AntimodeMenu.tsx | 114 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 src/client/views/AntimodeMenu.tsx (limited to 'src/client/views/AntimodeMenu.tsx') diff --git a/src/client/views/AntimodeMenu.tsx b/src/client/views/AntimodeMenu.tsx new file mode 100644 index 000000000..9b0ba6312 --- /dev/null +++ b/src/client/views/AntimodeMenu.tsx @@ -0,0 +1,114 @@ +import React = require("react"); +import { observer } from "mobx-react"; +import { observable, action } from "mobx"; +import "./AntimodeMenu.scss"; + +export default abstract class AntimodeMenu extends React.Component { + protected _offsetY: number = 0; + protected _offsetX: number = 0; + protected _mainCont: React.RefObject = React.createRef(); + protected _dragging: boolean = false; + + @observable protected _top: number = -300; + @observable protected _left: number = -300; + @observable protected _opacity: number = 1; + @observable protected _transition: string = "opacity 0.5s"; + @observable protected _transitionDelay: string = ""; + + @observable public Pinned: boolean = false; + + @action + public jumpTo = (x: number, y: number, forceJump: boolean = false) => { + if (!this.Pinned || forceJump) { + this._transition = this._transitionDelay = ""; + this._opacity = 1; + this._left = x; + this._top = y; + } + } + + @action + public fadeOut = (forceOut: boolean) => { + if (!this.Pinned) { + if (this._opacity === 0.2) { + this._transition = "opacity 0.1s"; + this._transitionDelay = ""; + this._opacity = 0; + this._left = this._top = -300; + } + + if (forceOut) { + this._transition = ""; + this._transitionDelay = ""; + this._opacity = 0; + this._left = this._top = -300; + } + } + } + + @action + protected pointerLeave = (e: React.PointerEvent) => { + if (!this.Pinned) { + this._transition = "opacity 0.5s"; + this._transitionDelay = "1s"; + this._opacity = 0.2; + setTimeout(() => this.fadeOut(false), 3000); + } + } + + @action + protected pointerEntered = (e: React.PointerEvent) => { + this._transition = "opacity 0.1s"; + this._transitionDelay = ""; + this._opacity = 1; + } + + @action + protected togglePin = (e: React.MouseEvent) => { + this.Pinned = !this.Pinned; + } + + protected dragStart = (e: React.PointerEvent) => { + document.removeEventListener("pointermove", this.dragging); + document.addEventListener("pointermove", this.dragging); + document.removeEventListener("pointerup", this.dragEnd); + document.addEventListener("pointerup", this.dragEnd); + + this._offsetX = this._mainCont.current!.getBoundingClientRect().width - e.nativeEvent.offsetX; + this._offsetY = e.nativeEvent.offsetY; + + e.stopPropagation(); + e.preventDefault(); + } + + @action + protected dragging = (e: PointerEvent) => { + this._left = e.pageX - this._offsetX; + this._top = e.pageY - this._offsetY; + + e.stopPropagation(); + e.preventDefault(); + } + + protected dragEnd = (e: PointerEvent) => { + document.removeEventListener("pointermove", this.dragging); + document.removeEventListener("pointerup", this.dragEnd); + e.stopPropagation(); + e.preventDefault(); + } + + protected handleContextMenu = (e: React.MouseEvent) => { + e.stopPropagation(); + e.preventDefault(); + } + + protected getElement(buttons: JSX.Element[]) { + return ( +
+ {buttons} +
+
+ ); + } +} \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 1cb74bdb046a618fa017edca7de674992d067752 Mon Sep 17 00:00:00 2001 From: Stanley Yip Date: Sun, 13 Oct 2019 13:41:08 -0400 Subject: ahh --- src/client/views/AntimodeMenu.tsx | 14 ++++++++++++++ src/client/views/InkingCanvas.tsx | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) (limited to 'src/client/views/AntimodeMenu.tsx') diff --git a/src/client/views/AntimodeMenu.tsx b/src/client/views/AntimodeMenu.tsx index 9b0ba6312..408df8bc2 100644 --- a/src/client/views/AntimodeMenu.tsx +++ b/src/client/views/AntimodeMenu.tsx @@ -3,6 +3,10 @@ import { observer } from "mobx-react"; import { observable, action } from "mobx"; import "./AntimodeMenu.scss"; +/** + * This is an abstract class that serves as the base for a PDF-style or Marquee-style + * menu. To use this class, look at PDFMenu.tsx or MarqueeOptionsMenu.tsx for an example. + */ export default abstract class AntimodeMenu extends React.Component { protected _offsetY: number = 0; protected _offsetX: number = 0; @@ -18,6 +22,12 @@ export default abstract class AntimodeMenu extends React.Component { @observable public Pinned: boolean = false; @action + /** + * @param x + * @param y + * @param forceJump: If the menu is pinned down, do you want to force it to jump to the new location? + * Called when you want the menu to show up at a location + */ public jumpTo = (x: number, y: number, forceJump: boolean = false) => { if (!this.Pinned || forceJump) { this._transition = this._transitionDelay = ""; @@ -28,6 +38,10 @@ export default abstract class AntimodeMenu extends React.Component { } @action + /** + * @param forceOut: Do you want the menu to disappear immediately or to slowly fadeout? + * Called when you want the menu to disappear + */ public fadeOut = (forceOut: boolean) => { if (!this.Pinned) { if (this._opacity === 0.2) { diff --git a/src/client/views/InkingCanvas.tsx b/src/client/views/InkingCanvas.tsx index 1cfa8d644..0eb4c66a2 100644 --- a/src/client/views/InkingCanvas.tsx +++ b/src/client/views/InkingCanvas.tsx @@ -183,7 +183,7 @@ export class InkingCanvas extends React.Component { let svgCanvasStyle = InkingControl.Instance.selectedTool !== InkTool.None && !this.props.Document.isBackground ? "canSelect" : "noSelect"; return (
-
+
e.stopPropagation()} /> {this.props.children()} {this.drawnPaths}
-- cgit v1.2.3-70-g09d2