aboutsummaryrefslogtreecommitdiff
path: root/src/views/collections/CollectionDockingView.tsx
diff options
context:
space:
mode:
authorTyler Schicke <tyler_schicke@brown.edu>2019-02-01 01:12:31 -0500
committerTyler Schicke <tyler_schicke@brown.edu>2019-02-01 01:12:31 -0500
commit2cddac17b405aa85d488f12a0ee5e05ba8698eab (patch)
tree9b7c085eeab417c00fc32b656eacb0dae3ccb407 /src/views/collections/CollectionDockingView.tsx
parentd12625a3a3e241d80ce3fe8e577ba8a41320b189 (diff)
parentb2c95923e631bc4acae8bb3d10913704d8ec9939 (diff)
Merge branch 'master' of github-tsch-brown:browngraphicslab/Dash-Web
Diffstat (limited to 'src/views/collections/CollectionDockingView.tsx')
-rw-r--r--src/views/collections/CollectionDockingView.tsx172
1 files changed, 121 insertions, 51 deletions
diff --git a/src/views/collections/CollectionDockingView.tsx b/src/views/collections/CollectionDockingView.tsx
index 3d0c39c9d..a547ea1e8 100644
--- a/src/views/collections/CollectionDockingView.tsx
+++ b/src/views/collections/CollectionDockingView.tsx
@@ -4,7 +4,7 @@ import React = require("react");
import FlexLayout from "flexlayout-react";
import { action, observable, computed } from "mobx";
import { Document } from "../../fields/Document";
-import { DocumentView, CollectionViewProps } from "../nodes/DocumentView";
+import { DocumentView, CollectionViewProps, COLLECTION_BORDER_WIDTH } from "../nodes/DocumentView";
import { ListField } from "../../fields/ListField";
import { NumberField } from "../../fields/NumberField";
import { SSL_OP_SINGLE_DH_USE } from "constants";
@@ -15,6 +15,7 @@ import 'golden-layout/src/css/goldenlayout-base.css';
import 'golden-layout/src/css/goldenlayout-dark-theme.css';
import * as GoldenLayout from "golden-layout";
import * as ReactDOM from 'react-dom';
+import { DragManager } from "../../util/DragManager";
@observer
export class CollectionDockingView extends React.Component<CollectionViewProps> {
@@ -45,15 +46,16 @@ export class CollectionDockingView extends React.Component<CollectionViewProps>
var docs = value.map(doc => {
return { type: 'component', componentName: 'documentViewComponent', componentState: { doc: doc } };
});
- return new GoldenLayout({ content: [ { type: 'row', content: docs } ] });
+ return new GoldenLayout({
+ settings: {
+ selectionEnabled: true
+ }, content: [ { type: 'row', content: docs } ]
+ });
}
constructor(props: CollectionViewProps) {
super(props);
}
- public static BORDER_WIDTH = 2;
- public static TAB_HEADER_HEIGHT = 20;
-
@computed
public get active(): boolean {
var isSelected = (this.props.ContainingDocumentView != undefined && SelectionManager.IsSelected(this.props.ContainingDocumentView));
@@ -65,8 +67,12 @@ export class CollectionDockingView extends React.Component<CollectionViewProps>
componentDidMount: () => void = () => {
if (this._containerRef.current && CollectionDockingView.UseGoldenLayout) {
this.goldenLayoutFactory();
+ window.addEventListener('resize', this.onResize); // bcz: would rather add this event to the parent node, but resize events only come from Window
}
}
+ componentWillUnmount: () => void = () => {
+ window.removeEventListener('resize', this.onResize);
+ }
private nextId = (function () { var _next_id = 0; return function () { return _next_id++; } })();
@action
@@ -87,6 +93,15 @@ export class CollectionDockingView extends React.Component<CollectionViewProps>
ContextMenu.Instance.clearItems()
}
}
+
+ @action
+ onResize = (event: any) => {
+ var cur = this.props.ContainingDocumentView!.MainContent.current;
+
+ // bcz: since GoldenLayout isn't a React component itself, we need to notify it to resize when its document container's size has changed
+ CollectionDockingView.myLayout.updateSize(cur!.getBoundingClientRect().width, cur!.getBoundingClientRect().height);
+ }
+
@action
onPointerDown = (e: React.PointerEvent): void => {
if (e.button === 2 && this.active) {
@@ -116,31 +131,94 @@ export class CollectionDockingView extends React.Component<CollectionViewProps>
}
}
+ public static myLayout: any = null;
+
+ private static _dragDiv: any = null;
+ private static _dragParent: HTMLElement | null = null;
+ private static _dragElement: HTMLDivElement;
+ private static _dragFakeElement: HTMLDivElement;
+ public static StartOtherDrag(dragElement: HTMLDivElement, dragDoc: Document) {
+ var newItemConfig = {
+ type: 'component',
+ componentName: 'documentViewComponent',
+ componentState: { doc: dragDoc }
+ };
+ this._dragElement = dragElement;
+ this._dragParent = dragElement.parentElement;
+ // bcz: we want to copy this document into the header, not move it there.
+ // However, GoldenLayout is setup to move things, so we have to do some kludgy stuff:
+
+ // - create a temporary invisible div and register that as a DragSource with GoldenLayout
+ this._dragDiv = document.createElement("div");
+ this._dragDiv.style.opacity = 0;
+ DragManager.Root().appendChild(this._dragDiv);
+ CollectionDockingView.myLayout.createDragSource(this._dragDiv, newItemConfig);
+
+ // - add our document to that div so that GoldenLayout will get the move events its listening for
+ this._dragDiv.appendChild(this._dragElement);
+
+ // - add a duplicate of our document to the original document's container
+ // (GoldenLayout will be removing our original one)
+ this._dragFakeElement = dragElement.cloneNode(true) as HTMLDivElement;
+ this._dragParent!.appendChild(this._dragFakeElement);
+
+ // all of this must be undone when the document has been dropped (see tabCreated)
+ }
+
+ _makeFullScreen: boolean = false;
+ _maximizedStack: any = null;
+ public static OpenFullScreen(dv: DocumentView) {
+ var newItemConfig = {
+ type: 'component',
+ componentName: 'documentViewComponent',
+ componentState: { doc: dv.props.Document }
+ };
+ CollectionDockingView.myLayout._makeFullScreen = true;
+ CollectionDockingView.myLayout.root.contentItems[ 0 ].addChild(newItemConfig);
+ }
+ public static CloseFullScreen() {
+ if (CollectionDockingView.myLayout._maximizedStack != null) {
+ CollectionDockingView.myLayout._maximizedStack.header.controlsContainer.find('.lm_close').click();
+ CollectionDockingView.myLayout._maximizedStack = null;
+ }
+ }
goldenLayoutFactory() {
- var myLayout = this.modelForGoldenLayout;
+ CollectionDockingView.myLayout = this.modelForGoldenLayout;
- myLayout.on('stackCreated', function (stack: any) {
- stack.header.controlsContainer.find('.lm_close') //get the close icon
- .off('click') //unbind the current click handler
+ CollectionDockingView.myLayout.on('tabCreated', function (tab: any) {
+ if (CollectionDockingView._dragDiv) {
+ CollectionDockingView._dragDiv.removeChild(CollectionDockingView._dragElement);
+ CollectionDockingView._dragParent!.removeChild(CollectionDockingView._dragFakeElement);
+ CollectionDockingView._dragParent!.appendChild(CollectionDockingView._dragElement);
+ DragManager.Root().removeChild(CollectionDockingView._dragDiv);
+ CollectionDockingView._dragDiv = null;
+ }
+ tab.setTitle(tab.contentItem.config.componentState.doc.Title);
+ tab.closeElement.off('click') //unbind the current click handler
.click(function () {
- if (confirm('really close this?')) {
- stack.remove();
- }
+ //if (confirm('really close this?')) {
+ tab.contentItem.remove();
+ //}
});
});
- myLayout.on('tabCreated', function (tab: any) {
- tab.setTitle(tab.contentItem.config.componentState.doc.Title);
- tab.closeElement.off('click') //unbind the current click handler
+ CollectionDockingView.myLayout.on('stackCreated', function (stack: any) {
+ if (CollectionDockingView.myLayout._makeFullScreen) {
+ CollectionDockingView.myLayout._maximizedStack = stack;
+ CollectionDockingView.myLayout._maxstack = stack.header.controlsContainer.find('.lm_maximise');
+ }
+ stack.header.controlsContainer.find('.lm_popout').hide();
+ stack.header.controlsContainer.find('.lm_close') //get the close icon
+ .off('click') //unbind the current click handler
.click(function () {
- if (confirm('really close this?')) {
- tab.contentItem.remove();
- }
+ //if (confirm('really close this?')) {
+ stack.remove();
+ //}
});
});
var me = this;
- myLayout.registerComponent('documentViewComponent', function (container: any, state: any) {
+ CollectionDockingView.myLayout.registerComponent('documentViewComponent', function (container: any, state: any) {
// bcz: this is crufty
// calling html() causes a div tag to be added in the DOM with id 'containingDiv'.
// Apparently, we need to wait to allow a live html div element to actually be instantiated.
@@ -152,11 +230,14 @@ export class CollectionDockingView extends React.Component<CollectionViewProps>
<DocumentView key={state.doc.Id} Document={state.doc} ContainingCollectionView={me} ContainingDocumentView={me.props.ContainingDocumentView} />
),
document.getElementById(containingDiv)
- )
+ );
+ if (CollectionDockingView.myLayout._maxstack != null) {
+ CollectionDockingView.myLayout._maxstack.click();
+ }
}, 0);
});
- myLayout.container = this._containerRef.current;
- myLayout.init();
+ CollectionDockingView.myLayout.container = this._containerRef.current;
+ CollectionDockingView.myLayout.init();
}
@@ -168,35 +249,24 @@ export class CollectionDockingView extends React.Component<CollectionViewProps>
var w = Document.GetFieldValue(KeyStore.Width, NumberField, Number(0)) / s;
var h = Document.GetFieldValue(KeyStore.Height, NumberField, Number(0)) / s;
- if (CollectionDockingView.UseGoldenLayout) {
- return (
- <div className="border" style={{
- borderStyle: "solid",
- borderWidth: `${CollectionDockingView.BORDER_WIDTH}px`,
- }}>
- <div className="collectiondockingview-container" onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()} ref={this._containerRef}
- style={{
- width: "100%",
- height: "100%"
- }} >
- </div>
- </div>
- );
- } else {
- return (
- <div className="border" style={{
- borderStyle: "solid",
- borderWidth: `${CollectionDockingView.BORDER_WIDTH}px`,
- }}>
- <div className="collectiondockingview-container" onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()} ref={this._containerRef}
- style={{
- width: s > 1 ? "100%" : w - 2 * CollectionDockingView.BORDER_WIDTH,
- height: s > 1 ? "100%" : h - 2 * CollectionDockingView.BORDER_WIDTH
- }} >
- <FlexLayout.Layout model={this.modelForFlexLayout} factory={this.flexLayoutFactory} />
- </div>
- </div>
- );
+ var chooseLayout = () => {
+ if (!CollectionDockingView.UseGoldenLayout)
+ return <FlexLayout.Layout model={this.modelForFlexLayout} factory={this.flexLayoutFactory} />;
}
+
+ return (
+ <div className="border" style={{
+ borderStyle: "solid",
+ borderWidth: `${COLLECTION_BORDER_WIDTH}px`,
+ }}>
+ <div className="collectiondockingview-container" id="menuContainer" onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()} ref={this._containerRef}
+ style={{
+ width: CollectionDockingView.UseGoldenLayout || s > 1 ? "100%" : w - 2 * COLLECTION_BORDER_WIDTH,
+ height: CollectionDockingView.UseGoldenLayout || s > 1 ? "100%" : h - 2 * COLLECTION_BORDER_WIDTH
+ }} >
+ {chooseLayout()}
+ </div>
+ </div>
+ );
}
} \ No newline at end of file