From f0484119db20ac07345ee629a1e21671ad2247ca Mon Sep 17 00:00:00 2001 From: Melissa Zhang Date: Mon, 17 Aug 2020 14:54:24 -0700 Subject: GridView column number bug fixes, make up/down arrows more visible --- src/client/views/collections/CollectionMenu.scss | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/client/views/collections/CollectionMenu.scss') diff --git a/src/client/views/collections/CollectionMenu.scss b/src/client/views/collections/CollectionMenu.scss index 8658212b7..2f6d97f99 100644 --- a/src/client/views/collections/CollectionMenu.scss +++ b/src/client/views/collections/CollectionMenu.scss @@ -234,6 +234,10 @@ .collectionGridViewChrome-entryBox { width: 50%; } + + .collectionGridViewChrome-columnButton { + color: black; + } } -- cgit v1.2.3-70-g09d2 From 5adf15574ac6423e09617b3d756d98ea8cdc75c5 Mon Sep 17 00:00:00 2001 From: anika-ahluwalia Date: Mon, 17 Aug 2020 17:44:10 -0500 Subject: framework for web in top bar --- src/client/views/collections/CollectionMenu.scss | 51 ++++++++ src/client/views/collections/CollectionMenu.tsx | 156 +++++++++++++++++++++++ 2 files changed, 207 insertions(+) (limited to 'src/client/views/collections/CollectionMenu.scss') diff --git a/src/client/views/collections/CollectionMenu.scss b/src/client/views/collections/CollectionMenu.scss index 8658212b7..9d23c8647 100644 --- a/src/client/views/collections/CollectionMenu.scss +++ b/src/client/views/collections/CollectionMenu.scss @@ -311,6 +311,57 @@ } } +.webBox-urlEditor { + position: relative; + opacity: 0.9; + z-index: 9001; + transition: top .5s; + + .urlEditor { + display: grid; + grid-template-columns: 1fr auto; + padding-bottom: 10px; + overflow: hidden; + margin-top: 5px; + height: 35px; + + .editorBase { + display: flex; + + .editor-collapse { + transition: all .5s, opacity 0.3s; + position: absolute; + width: 40px; + transform-origin: top left; + } + + .switchToText { + color: $main-accent; + } + + .switchToText:hover { + color: $dark-color; + } + } + + button:hover { + transform: scale(1); + } + } +} + +.webpage-urlInput { + padding: 12px 10px 11px 10px; + border: 0px; + color: grey; + letter-spacing: 2px; + outline-color: black; + background: rgb(238, 238, 238); + width: 100%; + margin-right: 10px; + height: 100%; +} + .collectionFreeFormMenu-cont { display: inline-flex; position: relative; diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index 5119ff6c9..6fa907fc7 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -30,6 +30,7 @@ import { DocumentView } from "../nodes/DocumentView"; import RichTextMenu from "../nodes/formattedText/RichTextMenu"; import "./CollectionMenu.scss"; import { CollectionViewType, COLLECTION_BORDER_WIDTH } from "./CollectionView"; +import { WebField } from "../../../fields/URLField"; @observer export default class CollectionMenu extends AntimodeMenu { @@ -605,6 +606,158 @@ export class CollectionFreeFormViewChrome extends React.Component; } + @action + onUrlDrop = (e: React.DragEvent) => { + const { dataTransfer } = e; + const html = dataTransfer.getData("text/html"); + const uri = dataTransfer.getData("text/uri-list"); + const url = uri || html || this._url; + this._url = url.startsWith(window.location.origin) ? + url.replace(window.location.origin, this._url.match(/http[s]?:\/\/[^\/]*/)?.[0] || "") : url; + this.submitURL(); + e.stopPropagation(); + } + onUrlDragover = (e: React.DragEvent) => { + e.preventDefault(); + } + + @computed get _url() { + return this.selectedDoc ? Cast(this.selectedDoc["data"], WebField, null)?.url.toString() : "hello"; + } + + set _url(value) { this.selectedDoc && (this.selectedDoc["data"] = value); } + + @action + submitURL = () => { + if (!this._url.startsWith("http")) this._url = "http://" + this._url; + try { + const URLy = new URL(this._url); + const future = this.selectedDoc ? Cast(this.selectedDoc["data-future"], listSpec("string"), null) : null; + const history = this.selectedDoc ? Cast(this.selectedDoc["data-history"], listSpec("string"), null) : []; + const annos = this.selectedDoc ? DocListCast(this.selectedDoc["data-annotations"]) : undefined; + const url = this.selectedDoc ? Cast(this.selectedDoc["data"], WebField, null)?.url.toString() : null; + if (url) { + if (history === undefined) { + this.selectedDoc && (this.selectedDoc["data-history"] = new List([url])); + + } else { + history.push(url); + } + future && (future.length = 0); + this.selectedDoc && (this.selectedDoc["data-" + this.urlHash(url)] = new List(annos)); + } + this.selectedDoc && (this.selectedDoc["data"] = new WebField(URLy)); + this.selectedDoc && (this.selectedDoc["data-annotations"] = new List([])); + } catch (e) { + console.log("WebBox URL error:" + this._url); + } + } + + urlHash(s: string) { + return s.split('').reduce((a: any, b: any) => { a = ((a << 5) - a) + b.charCodeAt(0); return a & a; }, 0); + } + + toggleAnnotationMode = () => { + this.props.docView.layoutDoc.isAnnotating = !this.props.docView.layoutDoc.isAnnotating; + } + + @action + onURLChange = (e: React.ChangeEvent) => { + this._url = e.target.value; + } + + onValueKeyDown = async (e: React.KeyboardEvent) => { + if (e.key === "Enter") { + this.submitURL(); + } + e.stopPropagation(); + } + + @action + forward = () => { + const future = this.selectedDoc && (Cast(this.selectedDoc["data-future"], listSpec("string"), null)); + const history = this.selectedDoc && Cast(this.selectedDoc["data-history"], listSpec("string"), null); + if (future?.length) { + history?.push(this._url); + this.selectedDoc && (this.selectedDoc["data-annotations-" + this.urlHash(this._url)] = new List(DocListCast(this.selectedDoc["data-annotations"]))); + this.selectedDoc && (this.selectedDoc["data"] = new WebField(new URL(this._url = future.pop()!))); + this.selectedDoc && (this.selectedDoc["data-annotations"] = new List(DocListCast(this.selectedDoc["data-annotations" + "-" + this.urlHash(this._url)]))); + } + } + + @action + back = () => { + const future = this.selectedDoc && (Cast(this.selectedDoc["data-future"], listSpec("string"), null)); + const history = this.selectedDoc && Cast(this.selectedDoc["data-history"], listSpec("string"), null); + if (history?.length) { + if (future === undefined) this.selectedDoc && (this.selectedDoc["data-future"] = new List([this._url])); + else future.push(this._url); + this.selectedDoc && (this.selectedDoc["data-annotations" + "-" + this.urlHash(this._url)] = new List(DocListCast(this.selectedDoc["data-annotations"]))); + this.selectedDoc && (this.selectedDoc["data"] = new WebField(new URL(this._url = history.pop()!))); + this.selectedDoc && (this.selectedDoc["data-annotations"] = new List(DocListCast(this.selectedDoc["data-annotations" + "-" + this.urlHash(this._url)]))); + } + } + + private _keyInput = React.createRef(); + + @computed get urlEditor() { + return ( +
+
+
+
+
+ +
+
+ +
+ { + this._keyInput.current!.select(); + e.stopPropagation(); + }} + ref={this._keyInput} + /> +
+ + + +
+
+
+
+
+ ); + } + + @observable viewType = this.selectedDoc?._viewType; render() { @@ -646,6 +799,9 @@ export class CollectionFreeFormViewChrome extends React.Component } + {/* {!this.props.isOverlay || this.document.type !== DocumentType.WEB || this.isText || this.props.isDoc ? (null) : + this.urlEditor + } */} {!this.isText ? <> {this.drawButtons} -- cgit v1.2.3-70-g09d2 From f7e3823f957c2fc550aaa928e5286a4f5f90448b Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Tue, 18 Aug 2020 17:22:50 +0530 Subject: css --- src/client/views/collections/CollectionMenu.scss | 13 ++++++++++--- src/client/views/collections/CollectionMenu.tsx | 2 +- 2 files changed, 11 insertions(+), 4 deletions(-) (limited to 'src/client/views/collections/CollectionMenu.scss') diff --git a/src/client/views/collections/CollectionMenu.scss b/src/client/views/collections/CollectionMenu.scss index 8658212b7..9c0c0764d 100644 --- a/src/client/views/collections/CollectionMenu.scss +++ b/src/client/views/collections/CollectionMenu.scss @@ -229,11 +229,18 @@ .flexLabel { margin-bottom: 0; } - } - .collectionGridViewChrome-entryBox { - width: 50%; + .collectionGridViewChrome-entryBox { + width: 50%; + color: black; + } + + .columnButton { + color: black; + } } + + } diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index 3c0f65ff8..5c254510e 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -1037,7 +1037,7 @@ export class CollectionGridViewChrome extends React.Component - + -- cgit v1.2.3-70-g09d2 From 38cee0f811b7e2686fd75516d33c0ebfa7e1a2a1 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 25 Aug 2020 00:05:25 -0400 Subject: added URL for web pages and fixed forward/backward in menu bar. Fixed Go to reload web page. --- src/client/views/collections/CollectionMenu.scss | 4 +- src/client/views/collections/CollectionMenu.tsx | 191 +++++++++++------------ 2 files changed, 90 insertions(+), 105 deletions(-) (limited to 'src/client/views/collections/CollectionMenu.scss') diff --git a/src/client/views/collections/CollectionMenu.scss b/src/client/views/collections/CollectionMenu.scss index d0bfd0a41..21312e5f3 100644 --- a/src/client/views/collections/CollectionMenu.scss +++ b/src/client/views/collections/CollectionMenu.scss @@ -357,11 +357,13 @@ .webpage-urlInput { padding: 12px 10px 11px 10px; border: 0px; - color: grey; + color: black; + font-size: 10px; letter-spacing: 2px; outline-color: black; background: rgb(238, 238, 238); width: 100%; + min-width: 350px; margin-right: 10px; height: 100%; } diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index 3004176a0..80b4a3cd0 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -5,7 +5,7 @@ import { Tooltip } from "@material-ui/core"; import { action, computed, Lambda, observable, reaction, runInAction } from "mobx"; import { observer } from "mobx-react"; import { ColorState } from "react-color"; -import { Doc, DocListCast, Opt } from "../../../fields/Doc"; +import { Doc, DocListCast, Opt, Field } from "../../../fields/Doc"; import { Document } from "../../../fields/documentSchemas"; import { Id } from "../../../fields/FieldSymbols"; import { InkTool } from "../../../fields/InkField"; @@ -404,6 +404,7 @@ export class CollectionViewBaseChrome extends React.Component { setupMoveUpEvents(this, e, this.onAliasButtonMoved, emptyFunction, emptyFunction); } + @undoBatch onAliasButtonMoved = (e: PointerEvent) => { if (this._dragRef.current && this.selectedDoc) { @@ -702,15 +703,14 @@ export class CollectionFreeFormViewChrome extends React.Component; } - @action onUrlDrop = (e: React.DragEvent) => { const { dataTransfer } = e; const html = dataTransfer.getData("text/html"); const uri = dataTransfer.getData("text/uri-list"); const url = uri || html || this._url; - this._url = url.startsWith(window.location.origin) ? + const newurl = url.startsWith(window.location.origin) ? url.replace(window.location.origin, this._url.match(/http[s]?:\/\/[^\/]*/)?.[0] || "") : url; - this.submitURL(); + this.submitURL(newurl); e.stopPropagation(); } onUrlDragover = (e: React.DragEvent) => { @@ -718,34 +718,45 @@ export class CollectionFreeFormViewChrome extends React.Component { - if (!this._url.startsWith("http")) this._url = "http://" + this._url; + submitURL = (url: string) => { + if (!url.startsWith("http")) url = "http://" + url; try { - const URLy = new URL(this._url); - const future = this.selectedDoc ? Cast(this.selectedDoc["data-future"], listSpec("string"), null) : null; - const history = this.selectedDoc ? Cast(this.selectedDoc["data-history"], listSpec("string"), null) : []; - const annos = this.selectedDoc ? DocListCast(this.selectedDoc["data-annotations"]) : undefined; - const url = this.selectedDoc ? Cast(this.selectedDoc.data, WebField, null)?.url.toString() : null; - if (url) { - if (history === undefined) { - this.selectedDoc && (this.selectedDoc["data-history"] = new List([url])); - + const selectedDoc = this.selectedDoc; + if (selectedDoc) { + const URLy = new URL(url); + const future = Cast(selectedDoc["data-future"], listSpec("string"), null); + const history = Cast(selectedDoc["data-history"], listSpec("string"), null); + const annos = DocListCast(selectedDoc["data-annotations"]); + if (Field.toString(selectedDoc.data as Field) === Field.toString(new WebField(URLy))) { + Doc.GetProto(selectedDoc).data = undefined; + setTimeout(action(() => Doc.GetProto(selectedDoc).data = new WebField(URLy)), 0); } else { - history.push(url); + if (url) { + Doc.GetProto(selectedDoc)["data-annotations-" + this.urlHash(this._url)] = new List(annos); + if (history === undefined) { + selectedDoc["data-history"] = new List([this._url]); + } else { + history.push(this._url); + } + future && (future.length = 0); + } + Doc.GetProto(selectedDoc).data = new WebField(URLy); + const annots = Doc.GetProto(selectedDoc)["data-annotations-" + this.urlHash(url)]; + Doc.GetProto(selectedDoc)["data-annotations"] = annots instanceof ObjectField ? ObjectField.MakeCopy(annots) : new List([]); } - future && (future.length = 0); - this.selectedDoc && (this.selectedDoc["data-" + this.urlHash(url)] = new List(annos)); } - this.selectedDoc && (this.selectedDoc.data = new WebField(URLy)); - this.selectedDoc && (this.selectedDoc["data-annotations"] = new List([])); } catch (e) { - console.log("WebBox URL error:" + this._url); + console.log("WebBox URL error:" + url); } } @@ -753,44 +764,41 @@ export class CollectionFreeFormViewChrome extends React.Component { a = ((a << 5) - a) + b.charCodeAt(0); return a & a; }, 0); } - toggleAnnotationMode = () => { - this.props.docView.layoutDoc.isAnnotating = !this.props.docView.layoutDoc.isAnnotating; - } - - @action - onURLChange = (e: React.ChangeEvent) => { - this._url = e.target.value; - } - onValueKeyDown = async (e: React.KeyboardEvent) => { - if (e.key === "Enter") { - this.submitURL(); - } + e.key === "Enter" && this.submitURL(this._keyInput.current!.value); e.stopPropagation(); } @action forward = () => { - const future = this.selectedDoc && (Cast(this.selectedDoc["data-future"], listSpec("string"), null)); - const history = this.selectedDoc && Cast(this.selectedDoc["data-history"], listSpec("string"), null); - if (future?.length) { - history?.push(this._url); - this.selectedDoc && (this.selectedDoc["data-annotations-" + this.urlHash(this._url)] = new List(DocListCast(this.selectedDoc["data-annotations"]))); - this.selectedDoc && (this.selectedDoc.data = new WebField(new URL(this._url = future.pop()!))); - this.selectedDoc && (this.selectedDoc["data-annotations"] = new List(DocListCast(this.selectedDoc["data-annotations" + "-" + this.urlHash(this._url)]))); + const selectedDoc = this.selectedDoc; + if (selectedDoc) { + const future = Cast(selectedDoc["data-future"], listSpec("string"), null); + const history = Cast(selectedDoc["data-history"], listSpec("string"), null); + if (future?.length) { + history?.push(this._url); + Doc.GetProto(selectedDoc)["data-annotations-" + this.urlHash(this._url)] = new List(DocListCast(selectedDoc["data-annotations"])); + const newurl = future.pop()!; + Doc.GetProto(selectedDoc).data = new WebField(new URL(this._url = newurl)); + Doc.GetProto(selectedDoc)["data-annotations"] = new List(DocListCast(selectedDoc["data-annotations-" + this.urlHash(newurl)])); + } } } @action back = () => { - const future = this.selectedDoc && (Cast(this.selectedDoc["data-future"], listSpec("string"), null)); - const history = this.selectedDoc && Cast(this.selectedDoc["data-history"], listSpec("string"), null); - if (history?.length) { - if (future === undefined) this.selectedDoc && (this.selectedDoc["data-future"] = new List([this._url])); - else future.push(this._url); - this.selectedDoc && (this.selectedDoc["data-annotations" + "-" + this.urlHash(this._url)] = new List(DocListCast(this.selectedDoc["data-annotations"]))); - this.selectedDoc && (this.selectedDoc.data = new WebField(new URL(this._url = history.pop()!))); - this.selectedDoc && (this.selectedDoc["data-annotations"] = new List(DocListCast(this.selectedDoc["data-annotations" + "-" + this.urlHash(this._url)]))); + const selectedDoc = this.selectedDoc; + if (selectedDoc) { + const future = Cast(selectedDoc["data-future"], listSpec("string"), null); + const history = Cast(selectedDoc["data-history"], listSpec("string"), null); + if (history?.length) { + if (future === undefined) selectedDoc["data-future"] = new List([this._url]); + else future.push(this._url); + Doc.GetProto(selectedDoc)["data-annotations-" + this.urlHash(this._url)] = new List(DocListCast(selectedDoc["data-annotations"])); + const newurl = history.pop()!; + Doc.GetProto(selectedDoc).data = new WebField(new URL(this._url = newurl)); + Doc.GetProto(selectedDoc)["data-annotations"] = new List(DocListCast(selectedDoc["data-annotations-" + this.urlHash(newurl)])); + } } } @@ -798,56 +806,31 @@ export class CollectionFreeFormViewChrome extends React.Component -
-
-
-
- -
-
- -
- { - this._keyInput.current!.select(); - e.stopPropagation(); - }} - ref={this._keyInput} - /> -
- - - -
-
-
+ onDragOver={this.onUrlDragover} style={{ display: "flex" }}> + { + this._keyInput.current!.select(); + e.stopPropagation(); + }} + ref={this._keyInput} + /> +
+ + +
); @@ -884,20 +867,20 @@ export class CollectionFreeFormViewChrome extends React.Component : null} {!this.props.isOverlay || this.document.type !== DocumentType.WEB || this.isText || this.props.isDoc ? (null) : - Use Hypothesis} placement="bottom"> + Toggle between native iframe and annotation modes} placement="bottom"> } - {/* {!this.props.isOverlay || this.document.type !== DocumentType.WEB || this.isText || this.props.isDoc ? (null) : + {!this.props.isOverlay || this.document.type !== DocumentType.WEB || this.isText || this.props.isDoc ? (null) : this.urlEditor - } */} + } {!this.isText ? <> {this.drawButtons} -- cgit v1.2.3-70-g09d2 From a55c1ef0211cef68bebdb83b7ee8723c7bcf6edc Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 1 Sep 2020 12:25:34 -0400 Subject: fixed tabs to never select/switch on hover unless dragging. fixed display of highlight icons in menu bar. fixed placement of docDecorations level selector. --- src/client/util/DocumentManager.ts | 2 +- src/client/views/DocumentDecorations.scss | 2 +- src/client/views/InkingStroke.tsx | 2 +- src/client/views/MainView.tsx | 18 ++--- .../views/collections/CollectionDockingView.scss | 2 +- src/client/views/collections/CollectionMenu.scss | 4 ++ src/client/views/collections/TabDocView.tsx | 83 +++++++++++----------- src/client/views/nodes/DocumentContentsView.tsx | 3 +- src/client/views/nodes/FontIconBox.scss | 17 ++++- src/client/views/nodes/FontIconBox.tsx | 7 +- src/client/views/nodes/MenuIconBox.scss | 49 ------------- src/client/views/nodes/MenuIconBox.tsx | 33 --------- 12 files changed, 79 insertions(+), 143 deletions(-) delete mode 100644 src/client/views/nodes/MenuIconBox.scss delete mode 100644 src/client/views/nodes/MenuIconBox.tsx (limited to 'src/client/views/collections/CollectionMenu.scss') diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index 9e55c5a44..2c7dcf49b 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -161,7 +161,7 @@ export class DocumentManager { } else { const contView = docContext && getFirstDocView(docContext, originatingDoc); - contView && contView.topMost && contView.select(false); + contView && contView.topMost && contView.select(false); // bcz: change this to a function prop: popTab() that will make sure the tab for the document is topmost; docView.select(false); docView.props.Document.hidden && (docView.props.Document.hidden = undefined); docView.props.focus(docView.props.Document, willZoom, undefined, focusAndFinish); diff --git a/src/client/views/DocumentDecorations.scss b/src/client/views/DocumentDecorations.scss index 8291d7212..e02408559 100644 --- a/src/client/views/DocumentDecorations.scss +++ b/src/client/views/DocumentDecorations.scss @@ -21,7 +21,7 @@ $linkGap : 3px; background: none; } - .documentDecorations-selector { + .documentDecorations-levelSelector { pointer-events: auto; height: 15px; width: 15px; diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx index 1a1a3d75c..da98eca73 100644 --- a/src/client/views/InkingStroke.tsx +++ b/src/client/views/InkingStroke.tsx @@ -119,7 +119,7 @@ export class InkingStroke extends ViewBoxBaseComponent 5 ? strokeColor : "transparent", strokeWidth, (strokeWidth + 15), StrCast(this.layoutDoc.strokeBezier), StrCast(this.layoutDoc.fillColor, "none"), - "none", "none", undefined, scaleX, scaleY, "", this.props.active() ? "visiblepainted" : "none", false, true); + "none", "none", undefined, scaleX, scaleY, "", "visiblepainted", false, true); //points for adding const apoints = InteractionUtils.CreatePoints(data, left, top, strokeColor, strokeWidth, strokeWidth, diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 01df10aa0..7dddd1669 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -285,7 +285,7 @@ export class MainView extends React.Component { setupMoveUpEvents(this, e, action(e => (this._flyoutWidth = Math.max(e.clientX - 58, 0)) ? false : false), () => this._flyoutWidth < 5 && this.closeFlyout(), - this.toggleFlyout); + this.closeFlyout); } flyoutWidthFunc = () => this._flyoutWidth; @@ -382,11 +382,7 @@ export class MainView extends React.Component { SearchBox.Instance.enter(undefined); break; default: - this._sidebarContent.proto = button.target as any; - closed && this.expandFlyout(); - button._backgroundColor = "lightgrey"; - button.color = "black"; - this._lastButton = button; + closed && this.expandFlyout(button); } } return true; @@ -424,8 +420,14 @@ export class MainView extends React.Component { ; } - expandFlyout = action(() => this._flyoutWidth = (this._flyoutWidth || 250)); - toggleFlyout = action(() => this._flyoutWidth < 15 ? this.expandFlyout() : this.closeFlyout()); + expandFlyout = action((button: Doc) => { + this._flyoutWidth = (this._flyoutWidth || 250); + this._sidebarContent.proto = button.target as any; + button._backgroundColor = "lightgrey"; + button.color = "black"; + this._lastButton = button; + }); + closeFlyout = action(() => { this._lastButton && (this._lastButton.color = "white"); this._lastButton && (this._lastButton._backgroundColor = ""); diff --git a/src/client/views/collections/CollectionDockingView.scss b/src/client/views/collections/CollectionDockingView.scss index d3be1636d..96f5afcd9 100644 --- a/src/client/views/collections/CollectionDockingView.scss +++ b/src/client/views/collections/CollectionDockingView.scss @@ -70,7 +70,7 @@ margin: auto; } - .collectionDockingView-dragAsDocument { + .collectionDockingView-drag { touch-action: none; position: absolute; padding-left: 5px; diff --git a/src/client/views/collections/CollectionMenu.scss b/src/client/views/collections/CollectionMenu.scss index 21312e5f3..e36e5caa7 100644 --- a/src/client/views/collections/CollectionMenu.scss +++ b/src/client/views/collections/CollectionMenu.scss @@ -377,6 +377,7 @@ .antimodeMenu-button { text-align: center; display: block; + position: relative; } .color-previewI { @@ -384,12 +385,15 @@ height: 20%; bottom: 0; position: absolute; + margin-left: 2px; } .color-previewII { width: 80%; height: 80%; margin-left: 10%; + position: absolute; + bottom: 5; } .btn-group { diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx index 3cb57f086..3c230537c 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -53,67 +53,70 @@ export class TabDocView extends React.Component { tab._disposers = {} as { [name: string]: IReactionDisposer }; tab.contentItem.config.fixed && (tab.contentItem.parent.config.fixed = true); tab.DashDoc = doc; + CollectionDockingView.Instance.tabMap.add(tab); + // setup the title element and set its size according to the # of chars in the title. Show the full title when clicked. const titleEle = tab.titleElement[0]; - CollectionDockingView.Instance.tabMap.add(tab); - titleEle.onchange = (e: any) => { - titleEle.size = e.currentTarget.value.length + 3; - Doc.GetProto(doc).title = e.currentTarget.value; - }; titleEle.size = StrCast(doc.title).length + 3; titleEle.value = doc.title; titleEle.style["max-width"] = "100px"; - const gearSpan = document.createElement("span"); - gearSpan.className = "collectionDockingView-gear"; - gearSpan.style.position = "relative"; - gearSpan.style.paddingLeft = "0px"; - gearSpan.style.paddingRight = "12px"; - const stack = tab.contentItem.parent; - tab.element[0].onclick = (e: any) => { - if (e.target.className !== "lm_close_tab" && this.view) { - SelectionManager.SelectDoc(this.view, false); - if (Date.now() - titleEle.lastClick < 1000) titleEle.select(); - titleEle.lastClick = Date.now(); - (document.activeElement !== titleEle) && titleEle.focus(); - } + titleEle.onchange = (e: any) => { + titleEle.size = e.currentTarget.value.length + 3; + Doc.GetProto(doc).title = e.currentTarget.value; }; // shifts the focus to this tab when another tab is dragged over it tab.element[0].onmouseenter = (e: MouseEvent) => { if (SnappingManager.GetIsDragging() && tab.contentItem !== tab.header.parent.getActiveContentItem()) { tab.header.parent.setActiveContentItem(tab.contentItem); + console.log("Seetting " + titleEle.value); + tab.setActive(true); } - tab.setActive(true); }; - const onDown = (e: React.PointerEvent) => { + const onPointerDown = (e: React.PointerEvent) => { setupMoveUpEvents(this, e, (e) => { - !e.defaultPrevented && DragManager.StartDocumentDrag([gearSpan], new DragManager.DocumentDragData([doc], doc.dropAction as dropActionType), e.clientX, e.clientY); + !e.defaultPrevented && DragManager.StartDocumentDrag([dragHdl], new DragManager.DocumentDragData([doc], doc.dropAction as dropActionType), e.clientX, e.clientY); return !e.defaultPrevented; }, returnFalse, emptyFunction); }; - tab._disposers.selectionDisposer = reaction(() => SelectionManager.SelectedDocuments().some(v => v.topMost && v.props.Document === doc), - (selected) => { - selected && tab.contentItem !== tab.header.parent.getActiveContentItem() && UndoManager.RunInBatch(() => tab.header.parent.setActiveContentItem(tab.contentItem), "tab switch"); + // select the tab document when the tab is directly clicked and activate the tab whenver the tab document is selected + tab.element[0].onclick = (e: any) => { + if (e.target.className !== "lm_close_tab" && this.view) { + SelectionManager.SelectDoc(this.view, false); + if (Date.now() - titleEle.lastClick < 1000) titleEle.select(); + titleEle.lastClick = Date.now(); + (document.activeElement !== titleEle) && titleEle.focus(); } - ); - tab._disposers.buttonDisposer = reaction(() => this.view, - (view) => { - if (view) { - ReactDOM.render( - [view]} Stack={stack} /> - , - gearSpan); - tab._disposers.buttonDisposer?.(); - } - }, { fireImmediately: true }); + }; + tab._disposers.selectionDisposer = reaction(() => SelectionManager.SelectedDocuments().some(v => v.topMost && v.props.Document === doc), + (selected) => selected && tab.contentItem !== tab.header.parent.getActiveContentItem() && + UndoManager.RunInBatch(() => tab.header.parent.setActiveContentItem(tab.contentItem), "tab switch")); - tab.reactComponents = [gearSpan]; - tab.element.append(gearSpan); + //attach the selection doc buttons menu to the drag handle + const stack = tab.contentItem.parent; + const dragHdl = document.createElement("span"); + dragHdl.className = "collectionDockingView-gear"; + dragHdl.style.position = "relative"; + dragHdl.style.paddingLeft = "0px"; + dragHdl.style.paddingRight = "12px"; + tab._disposers.buttonDisposer = reaction(() => this.view, (view) => view && + [ReactDOM.render( + + [view]} Stack={stack} /> + , dragHdl), + tab._disposers.buttonDisposer?.()], + { fireImmediately: true }); + tab.reactComponents = [dragHdl]; + tab.element.append(dragHdl); + + // highlight the tab when the tab document is brushed in any part of the UI tab._disposers.reactionDisposer = reaction(() => ({ title: doc.title, degree: Doc.IsBrushedDegree(doc) }), ({ title, degree }) => { - tab.titleElement[0].value = title; - tab.titleElement[0].style.padding = degree ? 0 : 2; - tab.titleElement[0].style.border = `${["gray", "gray", "gray"][degree]} ${["none", "dashed", "solid"][degree]} 2px`; + titleEle.value = title; + titleEle.style.padding = degree ? 0 : 2; + titleEle.style.border = `${["gray", "gray", "gray"][degree]} ${["none", "dashed", "solid"][degree]} 2px`; }, { fireImmediately: true }); + + // clean up the tab when it is closed tab.closeElement.off('click') //unbind the current click handler .click(function () { Object.values(tab._disposers).forEach((disposer: any) => disposer?.()); diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx index dc9b7c98f..5d5a1f7f3 100644 --- a/src/client/views/nodes/DocumentContentsView.tsx +++ b/src/client/views/nodes/DocumentContentsView.tsx @@ -18,7 +18,6 @@ import { DocHolderBox } from "./DocHolderBox"; import { DocumentViewProps } from "./DocumentView"; import "./DocumentView.scss"; import { FontIconBox } from "./FontIconBox"; -import { MenuIconBox } from "./MenuIconBox"; import { FieldView, FieldViewProps } from "./FieldView"; import { FormattedTextBox, FormattedTextBoxProps } from "./formattedText/FormattedTextBox"; import { ImageBox } from "./ImageBox"; @@ -190,7 +189,7 @@ export class DocumentContentsView extends React.Component( const backgroundColor = StrCast(this.layoutDoc._backgroundColor, StrCast(this.rootDoc.backgroundColor, this.props.backgroundColor?.(this.rootDoc, this.props.renderDepth))); const shape = StrCast(this.layoutDoc.iconShape, "round"); const icon = StrCast(this.dataDoc.icon, "user") as any; - const presTrailsIcon = ; + const presSize = shape === 'round' ? 25 : 30; + const presTrailsIcon = ; const button =