aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbob <bcz@cs.brown.edu>2019-10-15 13:42:13 -0400
committerbob <bcz@cs.brown.edu>2019-10-15 13:42:13 -0400
commit03f86e3b7b450699073c47aa43af23d31e0765d4 (patch)
tree74a5066ca8f15cab25a626894edf8ea9e46d01cb /src
parent69d822d6c68b69e5bfeeff03942ea9bab71cecc3 (diff)
extensions for linearViews or nesting.
Diffstat (limited to 'src')
-rw-r--r--src/client/documents/Documents.ts2
-rw-r--r--src/client/views/CollectionLinearView.scss24
-rw-r--r--src/client/views/CollectionLinearView.tsx88
-rw-r--r--src/client/views/DocComponent.tsx2
-rw-r--r--src/client/views/InkingControl.tsx58
-rw-r--r--src/client/views/MainView.tsx80
-rw-r--r--src/client/views/collections/CollectionSubView.tsx1
-rw-r--r--src/client/views/nodes/DocumentView.tsx15
-rw-r--r--src/client/views/nodes/FontIconBox.tsx5
-rw-r--r--src/server/authentication/models/current_user_utils.ts26
10 files changed, 154 insertions, 147 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 5794a6bee..6df172f46 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -471,7 +471,7 @@ export namespace Docs {
}
export function LinearDocument(documents: Array<Doc>, options: DocumentOptions, id?: string) {
- return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { chromeStatus: "collapsed", schemaColumns: new List([new SchemaHeaderField("title", "#f1efeb")]), ...options, viewType: CollectionViewType.Linear }, id);
+ return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { chromeStatus: "collapsed", backgroundColor: "black", schemaColumns: new List([new SchemaHeaderField("title", "#f1efeb")]), ...options, viewType: CollectionViewType.Linear }, id);
}
export function SchemaDocument(schemaColumns: SchemaHeaderField[], documents: Array<Doc>, options: DocumentOptions) {
diff --git a/src/client/views/CollectionLinearView.scss b/src/client/views/CollectionLinearView.scss
index 4bfd88b69..4423a7020 100644
--- a/src/client/views/CollectionLinearView.scss
+++ b/src/client/views/CollectionLinearView.scss
@@ -4,26 +4,25 @@
.collectionLinearView-outer{
overflow: hidden;
height:100%;
- padding:5px;
.collectionLinearView {
display:flex;
+ height: 100%;
>label {
background: $dark-color;
color: $light-color;
display: inline-block;
border-radius: 18px;
- font-size: 25px;
- width: 36px;
- height: 36px;
- margin-right: 10px;
+ font-size: 12.5px;
+ width: 18px;
+ height: 18px;
+ margin-top:auto;
+ margin-bottom:auto;
cursor: pointer;
transition: transform 0.2s;
}
label p {
- padding-left: 10.5px;
- width: 500px;
- height: 500px;
+ padding-left:5px;
}
label:hover {
@@ -47,20 +46,21 @@
.collectionLinearView-content {
display: flex;
opacity: 1;
- padding: 0;
position: relative;
+ margin-top: auto;
.collectionLinearView-docBtn, .collectionLinearView-docBtn-scalable {
position:relative;
- margin-right: 10px;
+ margin-top: auto;
+ margin-bottom: auto;
}
.collectionLinearView-docBtn-scalable:hover {
transform: scale(1.15);
}
.collectionLinearView-round-button {
- width: 36px;
- height: 36px;
+ width: 18px;
+ height: 18px;
border-radius: 18px;
font-size: 15px;
}
diff --git a/src/client/views/CollectionLinearView.tsx b/src/client/views/CollectionLinearView.tsx
index 5c793f784..9d1dd7749 100644
--- a/src/client/views/CollectionLinearView.tsx
+++ b/src/client/views/CollectionLinearView.tsx
@@ -1,23 +1,20 @@
-import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { action, observable, computed, IReactionDisposer, reaction } from 'mobx';
+import { action, IReactionDisposer, observable, reaction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { Doc, DocListCast, Opt, HeightSym } from '../../new_fields/Doc';
-import { InkTool } from '../../new_fields/InkField';
+import { Doc, HeightSym, WidthSym } from '../../new_fields/Doc';
import { ObjectField } from '../../new_fields/ObjectField';
+import { makeInterface } from '../../new_fields/Schema';
import { ScriptField } from '../../new_fields/ScriptField';
-import { NumCast, StrCast } from '../../new_fields/Types';
-import { emptyFunction, returnEmptyString, returnOne, returnTrue, returnFalse, Utils } from '../../Utils';
+import { BoolCast, NumCast, StrCast } from '../../new_fields/Types';
+import { emptyFunction, returnEmptyString, returnOne, returnTrue, Utils } from '../../Utils';
import { Docs } from '../documents/Documents';
import { DragManager } from '../util/DragManager';
import { Transform } from '../util/Transform';
-import { UndoManager } from '../util/UndoManager';
-import { InkingControl } from './InkingControl';
-import { DocumentView, documentSchema } from './nodes/DocumentView';
import "./CollectionLinearView.scss";
-import { makeInterface } from '../../new_fields/Schema';
+import { CollectionViewType } from './collections/CollectionBaseView';
import { CollectionSubView } from './collections/CollectionSubView';
-import { DocumentType } from '../documents/DocumentTypes';
+import { documentSchema, DocumentView } from './nodes/DocumentView';
+import { translate } from 'googleapis/build/src/apis/translate';
type LinearDocument = makeInterface<[typeof documentSchema,]>;
@@ -26,7 +23,6 @@ const LinearDocument = makeInterface(documentSchema);
@observer
export class CollectionLinearView extends CollectionSubView(LinearDocument) {
@observable public addMenuToggle = React.createRef<HTMLInputElement>();
- @observable private _checked = false;
private _dropDisposer?: DragManager.DragDropDisposer;
private _heightDisposer?: IReactionDisposer;
@@ -37,12 +33,8 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
componentDidMount() {
// is there any reason this needs to exist? -syip. yes, it handles autoHeight for stacking views (masonry isn't yet supported).
- this._heightDisposer = reaction(() => NumCast(this.props.Document.height, 0) + this.childDocs.length + (this._checked ? 1 : 0),
- () => {
- if (true || this.props.Document.fitWidth) {
- this.props.Document.width = 36 + (this._checked ? this.childDocs.length * (this.props.Document[HeightSym]() + 10) : 10);
- }
- },
+ this._heightDisposer = reaction(() => NumCast(this.props.Document.height, 0) + this.childDocs.length + (this.props.Document.isExpanded ? 1 : 0),
+ () => this.props.Document.width = 18 + (this.props.Document.isExpanded ? this.childDocs.length * (this.props.Document[HeightSym]()) : 10),
{ fireImmediately: true }
);
}
@@ -56,11 +48,13 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
drop = action((e: Event, de: DragManager.DropEvent) => {
(de.data as DragManager.DocumentDragData).draggedDocuments.map((doc, i) => {
let dbox = doc;
- if (!doc.onDragStart && this.props.Document.convertToButtons) {
+ if (!doc.onDragStart && this.props.Document.convertToButtons && doc.viewType !== CollectionViewType.Linear) {
dbox = Docs.Create.FontIconDocument({ nativeWidth: 100, nativeHeight: 100, width: 100, height: 100, backgroundColor: StrCast(doc.backgroundColor), title: "Custom", icon: "bolt" });
dbox.dragFactory = doc;
dbox.removeDropProperties = doc.removeDropProperties instanceof ObjectField ? ObjectField.MakeCopy(doc.removeDropProperties) : undefined;
dbox.onDragStart = ScriptField.MakeFunction('getCopy(this.dragFactory, true)');
+ } else if (doc.viewType === CollectionViewType.Linear) {
+ dbox.ignoreClick = true;
}
(de.data as DragManager.DocumentDragData).droppedDocuments[i] = dbox;
});
@@ -68,40 +62,51 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
return super.drop(e, de);
});
- selected = (tool: InkTool) => {
- if (!InkingControl.Instance || InkingControl.Instance.selectedTool === InkTool.None) return { display: "none" };
- if (InkingControl.Instance.selectedTool === tool) {
- return { color: "#61aaa3", fontSize: "50%" };
- }
- return { fontSize: "50%" };
- }
-
public isCurrent(doc: Doc) { return !doc.isMinimized && (Math.abs(NumCast(doc.displayTimecode, -1) - NumCast(this.Document.currentTimecode, -1)) < 1.5 || NumCast(doc.displayTimecode, -1) === -1); }
- dimension = () => NumCast(this.props.Document.height) - 5;
+ dimension = () => NumCast(this.props.Document.height); // 2 * the padding
+ getTransform = (ele: React.RefObject<HTMLDivElement>) => () => {
+ if (!ele.current) return Transform.Identity();
+ let { scale, translateX, translateY } = Utils.GetScreenTransform(ele.current);
+ return new Transform(-translateX, -translateY, 1 / scale);
+ };
+ _spacing = 20;
render() {
let guid = Utils.GenerateGuid();
return <div className="collectionLinearView-outer">
<div className="collectionLinearView" ref={this.createDropTarget} >
- <input id={`${guid}`} type="checkbox" ref={this.addMenuToggle} onChange={action((e: any) => this._checked = this.addMenuToggle.current!.checked)} />
- <label htmlFor={`${guid}`} style={{ marginTop: (this.dimension() - 36) / 2, marginBottom: "auto" }} title="Close Menu"><p>+</p></label>
+ <input id={`${guid}`} type="checkbox" checked={BoolCast(this.props.Document.isExpanded)} ref={this.addMenuToggle}
+ onChange={action((e: any) => this.props.Document.isExpanded = this.addMenuToggle.current!.checked)} />
+ <label htmlFor={`${guid}`} style={{ marginTop: "auto", marginBottom: "auto", background: StrCast(this.props.Document.backgroundColor, "black") === StrCast(this.props.Document.color, "white") ? "black" : StrCast(this.props.Document.backgroundColor, "black") }} title="Close Menu"><p>+</p></label>
<div className="collectionLinearView-content">
- {this.childLayoutPairs.filter(pair => this.isCurrent(pair.layout)).map(pair =>
- <div className={`collectionLinearView-docBtn` + (pair.layout.onClick ? "-scalable" : "")} style={{ width: this.dimension(), height: this.dimension() }} key={StrCast(pair.layout.title)} >
+ {this.childLayoutPairs.filter(pair => this.isCurrent(pair.layout)).map(pair => {
+ let nested = pair.layout.viewType === CollectionViewType.Linear;
+ let dref = React.createRef<HTMLDivElement>();
+ let nativeWidth = NumCast(pair.layout.nativeWidth, this.dimension());
+ let scalingContent = nested ? 1 : this.dimension() / (this._spacing + nativeWidth);
+ let scalingBox = nested ? 1 : this.dimension() / nativeWidth;
+ let deltaSize = nativeWidth * scalingBox - nativeWidth * scalingContent;
+ return <div className={`collectionLinearView-docBtn` + (pair.layout.onClick || pair.layout.onDragStart ? "-scalable" : "")} key={StrCast(pair.layout.title)} ref={dref}
+ style={{
+ width: nested ? pair.layout[WidthSym]() : this.dimension(),
+ height: nested ? pair.layout[HeightSym]() : this.dimension(),
+ transform: nested ? undefined : `translate(${deltaSize / 2}px, ${deltaSize / 2}px)`
+ }} >
<DocumentView
Document={pair.layout}
DataDoc={pair.data}
addDocument={this.props.addDocument}
+ moveDocument={this.props.moveDocument}
addDocTab={this.props.addDocTab}
pinToPres={emptyFunction}
removeDocument={this.props.removeDocument}
ruleProvider={undefined}
onClick={undefined}
- ScreenToLocalTransform={Transform.Identity}
- ContentScaling={() => this.dimension() / (10 + NumCast(pair.layout.nativeWidth, this.dimension()))} // ugh - need to get rid of this inline function to avoid recomputing
- PanelWidth={this.dimension}
- PanelHeight={this.dimension}
+ ScreenToLocalTransform={this.getTransform(dref)}
+ ContentScaling={() => scalingContent} // ugh - need to get rid of this inline function to avoid recomputing
+ PanelWidth={() => nested ? pair.layout[WidthSym]() : this.dimension()}
+ PanelHeight={() => nested ? pair.layout[HeightSym]() : this.dimension()}
renderDepth={this.props.renderDepth + 1}
focus={emptyFunction}
backgroundColor={returnEmptyString}
@@ -113,15 +118,10 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
zoomToScale={emptyFunction}
getScale={returnOne}>
</DocumentView>
- </div>)}
+ </div>
+ })}
{/* <li key="undoTest"><button className="add-button round-button" title="Click if undo isn't working" onClick={() => UndoManager.TraceOpenBatches()}><FontAwesomeIcon icon="exclamation" size="sm" /></button></li> */}
- {this.props.showHiddenControls ? <>
- <button className="collectionLinearView-toolbar-button collectionLinearView-round-button" title="Ink" onClick={() => InkingControl.Instance.toggleDisplay()}><FontAwesomeIcon icon="pen-nib" size="sm" /> </button>
- <button key="pen" onClick={() => InkingControl.Instance.switchTool(InkTool.Pen)} title="Pen" style={this.selected(InkTool.Pen)}><FontAwesomeIcon icon="pen" size="lg" /></button>
- <button key="marker" onClick={() => InkingControl.Instance.switchTool(InkTool.Highlighter)} title="Highlighter" style={this.selected(InkTool.Highlighter)}><FontAwesomeIcon icon="highlighter" size="lg" /></button>
- <button key="eraser" onClick={() => InkingControl.Instance.switchTool(InkTool.Eraser)} title="Eraser" style={this.selected(InkTool.Eraser)}><FontAwesomeIcon icon="eraser" size="lg" /></button>
- <InkingControl />
- </> : (null)}
+
</div>
</div>
</div>;
diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx
index b05966bb5..fbc27192c 100644
--- a/src/client/views/DocComponent.tsx
+++ b/src/client/views/DocComponent.tsx
@@ -36,7 +36,7 @@ export function DocStaticComponent<P extends DocStaticProps, T>(schemaCtor: (doc
get Document(): T {
return schemaCtor(this.props.Document);
}
- active = () => (this.props.Document.forceActive || this.props.isSelected() || this.props.renderDepth === 0) && !InkingControl.Instance.selectedTool;
+ active = () => (this.props.Document.forceActive || this.props.isSelected() || this.props.renderDepth === 0);// && !InkingControl.Instance.selectedTool; // bcz: inking state shouldn't affect static tools
}
return Component;
}
diff --git a/src/client/views/InkingControl.tsx b/src/client/views/InkingControl.tsx
index d42d8d2d9..41dec9f83 100644
--- a/src/client/views/InkingControl.tsx
+++ b/src/client/views/InkingControl.tsx
@@ -1,38 +1,30 @@
-import { observable, action, computed, runInAction } from "mobx";
+import { action, computed, observable } from "mobx";
import { ColorResult } from 'react-color';
-import React = require("react");
-import { observer } from "mobx-react";
-import "./InkingControl.scss";
-import { library } from '@fortawesome/fontawesome-svg-core';
-import { faPen, faHighlighter, faEraser, faBan } from '@fortawesome/free-solid-svg-icons';
-import { SelectionManager } from "../util/SelectionManager";
-import { InkTool } from "../../new_fields/InkField";
import { Doc } from "../../new_fields/Doc";
-import { undoBatch, UndoManager } from "../util/UndoManager";
-import { StrCast, NumCast, Cast } from "../../new_fields/Types";
-import { listSpec } from "../../new_fields/Schema";
+import { InkTool } from "../../new_fields/InkField";
import { List } from "../../new_fields/List";
+import { listSpec } from "../../new_fields/Schema";
+import { Cast, NumCast, StrCast } from "../../new_fields/Types";
import { Utils } from "../../Utils";
+import { Scripting } from "../util/Scripting";
+import { SelectionManager } from "../util/SelectionManager";
+import { undoBatch, UndoManager } from "../util/UndoManager";
-library.add(faPen, faHighlighter, faEraser, faBan);
-@observer
-export class InkingControl extends React.Component {
+export class InkingControl {
@observable static Instance: InkingControl;
@observable private _selectedTool: InkTool = InkTool.None;
@observable private _selectedColor: string = "rgb(244, 67, 54)";
@observable private _selectedWidth: string = "5";
@observable public _open: boolean = false;
- constructor(props: Readonly<{}>) {
- super(props);
- runInAction(() => InkingControl.Instance = this);
+ constructor() {
+ InkingControl.Instance = this;
}
- @action
- switchTool = (tool: InkTool): void => {
+ switchTool = action((tool: InkTool): void => {
this._selectedTool = tool;
- }
+ })
decimalToHexString(number: number) {
if (number < 0) {
number = 0xFFFFFFFF + number + 1;
@@ -124,22 +116,10 @@ export class InkingControl extends React.Component {
return this._selectedWidth;
}
- @action
- toggleDisplay = () => {
- this._open = !this._open;
- this.switchTool(this._open ? InkTool.Pen : InkTool.None);
- }
- render() {
- return (
- <ul className="inking-control" style={this._open ? { display: "flex" } : { display: "none" }}>
- <li className="ink-size ink-panel">
- <label htmlFor="stroke-width">SIZE: </label>
- <input type="text" min="1" max="100" value={this._selectedWidth} name="stroke-width"
- onChange={(e: React.ChangeEvent<HTMLInputElement>) => this.switchWidth(e.target.value)} />
- <input type="range" min="1" max="100" value={this._selectedWidth} name="stroke-width"
- onChange={(e: React.ChangeEvent<HTMLInputElement>) => this.switchWidth(e.target.value)} />
- </li>
- </ul >
- );
- }
-} \ No newline at end of file
+}
+Scripting.addGlobal(function activatePen() { return InkingControl.Instance.switchTool(InkTool.Pen); });
+Scripting.addGlobal(function activateBrush() { return InkingControl.Instance.switchTool(InkTool.Highlighter); });
+Scripting.addGlobal(function activateEraser() { return InkingControl.Instance.switchTool(InkTool.Eraser); });
+Scripting.addGlobal(function deactivateInk() { return InkingControl.Instance.switchTool(InkTool.None); });
+Scripting.addGlobal(function setInkWidth(width: any) { return InkingControl.Instance.switchWidth(width); });
+Scripting.addGlobal(function setInkColor(color: any) { return InkingControl.Instance.updateSelectedColor(color); }); \ No newline at end of file
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 701f094e2..4e06763a4 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -1,5 +1,8 @@
import { library } from '@fortawesome/fontawesome-svg-core';
-import { faArrowDown, faArrowUp, faBolt, faCaretUp, faCat, faCheck, faChevronRight, faClone, faCloudUploadAlt, faCommentAlt, faCut, faEllipsisV, faExclamation, faFilePdf, faFilm, faFont, faGlobeAsia, faLongArrowAltRight, faMusic, faObjectGroup, faPause, faPenNib, faPlay, faPortrait, faRedoAlt, faThumbtack, faTree, faTv, faUndoAlt } from '@fortawesome/free-solid-svg-icons';
+import {
+ faArrowDown, faArrowUp, faBolt, faCaretUp, faCat, faCheck, faChevronRight, faClone, faCloudUploadAlt, faCommentAlt, faCut, faEllipsisV, faExclamation, faFilePdf, faFilm, faFont, faGlobeAsia, faLongArrowAltRight,
+ faMusic, faObjectGroup, faPause, faPenNib, faPen, faEraser, faPlay, faPortrait, faRedoAlt, faThumbtack, faTree, faTv, faUndoAlt
+} from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { action, computed, configure, observable, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
@@ -99,6 +102,8 @@ export class MainView extends React.Component {
library.add(faGlobeAsia);
library.add(faUndoAlt);
library.add(faRedoAlt);
+ library.add(faPen);
+ library.add(faEraser);
library.add(faPenNib);
library.add(faFilm);
library.add(faMusic);
@@ -450,37 +455,50 @@ export class MainView extends React.Component {
Doc.RemoveDocFromList(CurrentUserUtils.UserDocument.expandingButtons as Doc, "data", doc);
return true;
}
+ @action
+ moveButtonDoc = (doc: Doc, targetCollection: Doc, addDocument: (document: Doc) => boolean): boolean => {
+ return this.remButtonDoc(doc) && addDocument(doc);
+ }
+ buttonBarXf = () => {
+ if (!this._docBtnRef.current) return Transform.Identity();
+ let { scale, translateX, translateY } = Utils.GetScreenTransform(this._docBtnRef.current);
+ return new Transform(-translateX, -translateY, 1 / scale);
+ }
+ _docBtnRef = React.createRef<HTMLDivElement>();
@computed get docButtons() {
- return <div className="mainView-docButtons" style={{ left: (this._flyoutTranslate ? this.flyoutWidth : 0) + 20 }} >
- <MainViewNotifs />
- <CollectionLinearView
- Document={CurrentUserUtils.UserDocument.expandingButtons as Doc}
- DataDoc={undefined}
- fieldKey={"data"}
- fieldExt={""}
- showHiddenControls={true}
- select={emptyFunction}
- chromeCollapsed={true}
- active={returnFalse}
- isSelected={returnFalse}
- moveDocument={returnFalse}
- CollectionView={undefined}
- addDocument={this.addButtonDoc}
- addDocTab={this.addDocTabFunc}
- pinToPres={emptyFunction}
- removeDocument={this.remButtonDoc}
- ruleProvider={undefined}
- onClick={undefined}
- ScreenToLocalTransform={Transform.Identity}
- ContentScaling={returnOne}
- PanelWidth={this.flyoutWidthFunc}
- PanelHeight={this.getContentsHeight}
- renderDepth={0}
- focus={emptyFunction}
- whenActiveChanged={emptyFunction}
- ContainingCollectionView={undefined}
- ContainingCollectionDoc={undefined} />
- </div>;
+ console.log("stuff = " + this.flyoutWidthFunc() + " " + this.getContentsHeight());
+ if (CurrentUserUtils.UserDocument.expandingButtons instanceof Doc) {
+ return <div className="mainView-docButtons" ref={this._docBtnRef} style={{ left: (this._flyoutTranslate ? this.flyoutWidth : 0) + 20, height: "42px" }} >
+ <MainViewNotifs />
+ <CollectionLinearView
+ Document={CurrentUserUtils.UserDocument.expandingButtons as Doc}
+ DataDoc={undefined}
+ fieldKey={"data"}
+ fieldExt={""}
+ select={emptyFunction}
+ chromeCollapsed={true}
+ active={returnFalse}
+ isSelected={returnFalse}
+ moveDocument={this.moveButtonDoc}
+ CollectionView={undefined}
+ addDocument={this.addButtonDoc}
+ addDocTab={this.addDocTabFunc}
+ pinToPres={emptyFunction}
+ removeDocument={this.remButtonDoc}
+ ruleProvider={undefined}
+ onClick={undefined}
+ ScreenToLocalTransform={this.buttonBarXf}
+ ContentScaling={returnOne}
+ PanelWidth={this.flyoutWidthFunc}
+ PanelHeight={this.getContentsHeight}
+ renderDepth={0}
+ focus={emptyFunction}
+ whenActiveChanged={emptyFunction}
+ ContainingCollectionView={undefined}
+ ContainingCollectionDoc={undefined} />
+ </div>;
+ }
+ return (null);
}
render() {
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 6e8e4fa12..fdbe5339d 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -33,7 +33,6 @@ export interface CollectionViewProps extends FieldViewProps {
VisibleHeight?: () => number;
chromeCollapsed: boolean;
setPreviewCursor?: (func: (x: number, y: number, drag: boolean) => void) => void;
- showHiddenControls?: boolean; // hack for showing the undo/redo/ink controls in a linear view -- needs to be redone
}
export interface SubCollectionViewProps extends CollectionViewProps {
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 62264ea38..c0e5185c1 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -39,6 +39,7 @@ import { ImageField } from '../../../new_fields/URLField';
import SharingManager from '../../util/SharingManager';
import { Scripting } from '../../util/Scripting';
import { DictationOverlay } from '../DictationOverlay';
+import { CollectionViewType } from '../collections/CollectionBaseView';
library.add(fa.faEdit);
library.add(fa.faTrash);
@@ -105,7 +106,7 @@ export const documentSchema = createSchema({
dropAction: "string", // override specifying what should happen when this document is dropped (can be "alias" or "copy")
removeDropProperties: listSpec("string"), // properties that should be removed from the alias/copy/etc of this document when it is dropped
onClick: ScriptField, // script to run when document is clicked (can be overriden by an onClick prop)
- onDragStart: ScriptField, // script to run when document is dragged (without being selected). the script should return an Doc to drag.
+ onDragStart: ScriptField, // script to run when document is dragged (without being selected). the script should return the Doc to be dropped.
dragFactory: Doc, // the document that serves as the "template" for the onDragStart script
ignoreAspect: "boolean", // whether aspect ratio should be ignored when laying out or manipulating the document
autoHeight: "boolean", // whether the height of the document should be computed automatically based on its contents
@@ -167,7 +168,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
if (this._mainCont.current) {
let dragData = new DragManager.DocumentDragData([this.props.Document]);
const [left, top] = this.props.ScreenToLocalTransform().scale(this.props.ContentScaling()).inverse().transformPoint(0, 0);
- dragData.offset = this.Document.onDragStart ? [0, 0] : this.props.ScreenToLocalTransform().scale(this.props.ContentScaling()).transformDirection(x - left, y - top);
+ dragData.offset = this.props.ScreenToLocalTransform().scale(this.props.ContentScaling()).transformDirection(x - left, y - top);
dragData.dropAction = dropAction;
dragData.moveDocument = this.Document.onDragStart ? undefined : this.props.moveDocument;
dragData.applyAsTemplate = applyAsTemplate;
@@ -175,7 +176,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
handlers: {
dragComplete: action((emptyFunction))
},
- hideSource: !dropAction && !this.Document.onDragStart
+ hideSource: !dropAction && !this.Document.onDragStart && !this.Document.onClick
});
}
}
@@ -249,7 +250,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
this._hitTemplateDrag = true;
}
}
- if ((this.active || this.Document.onDragStart) && e.button === 0 && !this.Document.lockedPosition && !this.Document.inOverlay) e.stopPropagation(); // events stop at the lowest document that is active. if right dragging, we let it go through though to allow for context menu clicks. PointerMove callbacks should remove themselves if the move event gets stopPropagated by a lower-level handler (e.g, marquee drag);
+ if ((this.active || this.Document.onDragStart || this.Document.onClick) && e.button === 0 && !this.Document.lockedPosition && !this.Document.inOverlay) e.stopPropagation(); // events stop at the lowest document that is active. if right dragging, we let it go through though to allow for context menu clicks. PointerMove callbacks should remove themselves if the move event gets stopPropagated by a lower-level handler (e.g, marquee drag);
document.removeEventListener("pointermove", this.onPointerMove);
document.removeEventListener("pointerup", this.onPointerUp);
document.addEventListener("pointermove", this.onPointerMove);
@@ -261,9 +262,9 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
if (e.cancelBubble && this.active) {
document.removeEventListener("pointermove", this.onPointerMove); // stop listening to pointerMove if something else has stopPropagated it (e.g., the MarqueeView)
}
- else if (!e.cancelBubble && (SelectionManager.IsSelected(this) || this.props.parentActive() || this.Document.onDragStart) && !this.Document.lockedPosition && !this.Document.inOverlay) {
+ else if (!e.cancelBubble && (SelectionManager.IsSelected(this) || this.props.parentActive() || this.Document.onDragStart || this.Document.onClick) && !this.Document.lockedPosition && !this.Document.inOverlay) {
if (Math.abs(this._downX - e.clientX) > 3 || Math.abs(this._downY - e.clientY) > 3) {
- if (!e.altKey && (!this.topMost || this.Document.onDragStart) && e.buttons === 1) {
+ if (!e.altKey && (!this.topMost || this.Document.onDragStart || this.Document.onClick) && e.buttons === 1) {
document.removeEventListener("pointermove", this.onPointerMove);
document.removeEventListener("pointerup", this.onPointerUp);
this.startDragging(this._downX, this._downY, this.Document.dropAction ? this.Document.dropAction as any : e.ctrlKey || e.altKey ? "alias" : undefined, this._hitTemplateDrag);
@@ -684,7 +685,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
color: StrCast(this.Document.color),
outline: fullDegree && !borderRounding ? `${highlightColors[fullDegree]} ${highlightStyles[fullDegree]} ${localScale}px` : "solid 0px",
border: fullDegree && borderRounding ? `${highlightStyles[fullDegree]} ${highlightColors[fullDegree]} ${localScale}px` : undefined,
- background: backgroundColor,
+ background: this.props.Document.type === DocumentType.FONTICON || this.props.Document.viewType === CollectionViewType.Linear ? undefined : backgroundColor,
width: animwidth,
height: animheight,
transform: `scale(${this.props.Document.fitWidth ? 1 : this.props.ContentScaling()})`,
diff --git a/src/client/views/nodes/FontIconBox.tsx b/src/client/views/nodes/FontIconBox.tsx
index 3f5afb6d1..aa442cd92 100644
--- a/src/client/views/nodes/FontIconBox.tsx
+++ b/src/client/views/nodes/FontIconBox.tsx
@@ -5,6 +5,7 @@ import { createSchema, makeInterface } from '../../../new_fields/Schema';
import { DocComponent } from '../DocComponent';
import './FontIconBox.scss';
import { FieldView, FieldViewProps } from './FieldView';
+import { StrCast } from '../../../new_fields/Types';
const FontIconSchema = createSchema({
icon: "string"
});
@@ -16,6 +17,8 @@ export class FontIconBox extends DocComponent<FieldViewProps, FontIconDocument>(
public static LayoutString() { return FieldView.LayoutString(FontIconBox); }
render() {
- return <button className="fontIconBox-outerDiv" > <FontAwesomeIcon className="fontIconBox-icon" icon={this.Document.icon as any} size="sm" color="white" /> </button>;
+ return <button className="fontIconBox-outerDiv" style={{ background: StrCast(this.props.Document.backgroundColor) }}>
+ <FontAwesomeIcon className="fontIconBox-icon" icon={this.Document.icon as any} size="sm" color="white" />
+ </button>;
}
} \ No newline at end of file
diff --git a/src/server/authentication/models/current_user_utils.ts b/src/server/authentication/models/current_user_utils.ts
index 8af6bbfd5..c4b91dadd 100644
--- a/src/server/authentication/models/current_user_utils.ts
+++ b/src/server/authentication/models/current_user_utils.ts
@@ -12,6 +12,7 @@ import { ScriptField } from "../../../new_fields/ScriptField";
import { Cast, PromiseValue } from "../../../new_fields/Types";
import { Utils } from "../../../Utils";
import { RouteStore } from "../../RouteStore";
+import { InkingControl } from "../../../client/views/InkingControl";
export class CurrentUserUtils {
private static curr_id: string;
@@ -45,17 +46,21 @@ export class CurrentUserUtils {
// setup the "creator" buttons for the sidebar-- eg. the default set of draggable document creation tools
static setupCreatorButtons() {
- let docProtoData = [
- { title: "collection", icon: "folder", script: 'Docs.Create.FreeformDocument([], { nativeWidth: undefined, nativeHeight: undefined, width: 150, height: 100, title: "freeform" })' },
- { title: "web page", icon: "globe-asia", script: 'Docs.Create.WebDocument("https://en.wikipedia.org/wiki/Hedgehog", { width: 300, height: 300, title: "New Webpage" })' },
- { title: "image", icon: "cat", script: 'Docs.Create.ImageDocument("https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg", { width: 200, title: "an image of a cat" })' },
- { title: "button", icon: "bolt", script: 'Docs.Create.ButtonDocument({ width: 150, height: 50, title: "Button" })' },
- { title: "presentation", icon: "tv", script: 'Doc.UserDoc().curPresentation = Docs.Create.PresDocument(new List<Doc>(), { width: 200, height: 500, title: "a presentation trail" })' },
- { title: "import folder", icon: "cloud-upload-alt", script: 'Docs.Create.DirectoryImportDocument({ title: "Directory Import", width: 400, height: 400 })' },
+ let docProtoData: { title: string, icon: string, drag?: string, click?: string }[] = [
+ { title: "collection", icon: "folder", drag: 'Docs.Create.FreeformDocument([], { nativeWidth: undefined, nativeHeight: undefined, width: 150, height: 100, title: "freeform" })' },
+ { title: "web page", icon: "globe-asia", drag: 'Docs.Create.WebDocument("https://en.wikipedia.org/wiki/Hedgehog", { width: 300, height: 300, title: "New Webpage" })' },
+ { title: "image", icon: "cat", drag: 'Docs.Create.ImageDocument("https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg", { width: 200, title: "an image of a cat" })' },
+ { title: "button", icon: "bolt", drag: 'Docs.Create.ButtonDocument({ width: 150, height: 50, title: "Button" })' },
+ { title: "presentation", icon: "tv", drag: 'Doc.UserDoc().curPresentation = Docs.Create.PresDocument(new List<Doc>(), { width: 200, height: 500, title: "a presentation trail" })' },
+ { title: "import folder", icon: "cloud-upload-alt", drag: 'Docs.Create.DirectoryImportDocument({ title: "Directory Import", width: 400, height: 400 })' },
+ { title: "pen", icon: "pen-nib", click: 'activatePen(); setInkWidth(2);' },
+ { title: "highlighter", icon: "pen", click: 'activateBrush(); setInkWidth(20);' },
+ { title: "eraser", icon: "eraser", click: 'activateEraser();' },
+ { title: "none", icon: "pause", click: 'deactivateInk();' },
];
return docProtoData.map(data => Docs.Create.FontIconDocument({
- nativeWidth: 100, nativeHeight: 100, width: 100, height: 100,
- title: data.title, icon: data.icon, onDragStart: ScriptField.MakeFunction(data.script)
+ nativeWidth: 100, nativeHeight: 100, width: 100, height: 100, dropAction: data.click ? "alias" : undefined,
+ title: data.title, icon: data.icon, onDragStart: data.drag ? ScriptField.MakeFunction(data.drag) : undefined, onClick: data.click ? ScriptField.MakeScript(data.click) : undefined
}));
}
@@ -144,7 +149,7 @@ export class CurrentUserUtils {
doc.expandingButtons = Docs.Create.LinearDocument([doc.undoBtn as Doc, doc.redoBtn as Doc], {
title: "expanding buttons", gridGap: 5, xMargin: 5, yMargin: 5, height: 42, width: 100, boxShadow: "0 0",
- backgroundColor: "#eeeeee", preventTreeViewOpen: true, forceActive: true, lockedPosition: true, convertToButtons: true
+ backgroundColor: "black", preventTreeViewOpen: true, forceActive: true, lockedPosition: true, convertToButtons: true
});
}
@@ -165,6 +170,7 @@ export class CurrentUserUtils {
}
static updateUserDocument(doc: Doc) {
+ new InkingControl();
(doc.optionalRightCollection === undefined) && CurrentUserUtils.setupMobileUploads(doc);
(doc.noteTypes === undefined) && CurrentUserUtils.setupNoteTypes(doc);
(doc.overlays === undefined) && CurrentUserUtils.setupOverlays(doc);