Skip to content

Commit

Permalink
drag drop console cells
Browse files Browse the repository at this point in the history
  • Loading branch information
Madhu94 committed Nov 4, 2018
1 parent 0fad407 commit 1123548
Show file tree
Hide file tree
Showing 7 changed files with 1,417 additions and 1,027 deletions.
2 changes: 2 additions & 0 deletions packages/cells/package.json
Expand Up @@ -40,9 +40,11 @@
"@jupyterlab/outputarea": "^0.19.1",
"@jupyterlab/rendermime": "^0.19.1",
"@jupyterlab/services": "^3.2.1",
"@phosphor/algorithm": "^1.1.2",
"@phosphor/coreutils": "^1.3.0",
"@phosphor/messaging": "^1.2.2",
"@phosphor/signaling": "^1.2.2",
"@phosphor/virtualdom": "^1.1.2",
"@phosphor/widgets": "^1.6.0",
"react": "~16.4.2"
},
Expand Down
185 changes: 185 additions & 0 deletions packages/cells/src/cellDragUtils.ts
@@ -0,0 +1,185 @@
/*-----------------------------------------------------------------------------
| Copyright (c) Jupyter Development Team.
| Distributed under the terms of the Modified BSD License.
|----------------------------------------------------------------------------*/

import { each, IterableOrArrayLike } from '@phosphor/algorithm';
import { ICodeCellModel } from './model';
import { Cell } from './widget';
import { h, VirtualDOM } from '@phosphor/virtualdom';
import { nbformat } from '../../coreutils/lib';

/**
* The threshold in pixels to start a drag event.
*/
const DRAG_THRESHOLD = 5;
/**
* The class name added to drag images.
*/
const DRAG_IMAGE_CLASS = 'jp-dragImage';

/**
* The class name added to singular drag images
*/
const SINGLE_DRAG_IMAGE_CLASS = 'jp-dragImage-singlePrompt';

/**
* The class name added to the drag image cell content.
*/
const CELL_DRAG_CONTENT_CLASS = 'jp-dragImage-content';

/**
* The class name added to the drag image cell content.
*/
const CELL_DRAG_PROMPT_CLASS = 'jp-dragImage-prompt';

/**
* The class name added to the drag image cell content.
*/
const CELL_DRAG_MULTIPLE_BACK = 'jp-dragImage-multipleBack';

/**
* This module contains some utility functions to operate on cells. This
* could be shared by widgets that contain cells, like the CodeConsole or
* Notebook widgets.
*/

export namespace CellUtils {
/**
* Find the cell index containing the target html element.
* This function traces up the DOM hierarchy to find the root cell
* node. Then find the corresponding child and select it.
*
* @param node - the cell node or a child of the cell node.
* @param cells - an iterable of Cells
* @param isCellNode - a function that takes in a node and checks if
* it is a cell node.
*/
export function findCell(
node: HTMLElement,
cells: IterableOrArrayLike<Cell>,
isCellNode: (node: HTMLElement) => boolean
): number {
let cellIndex: number = -1;
while (node && node !== document.body) {
if (isCellNode(node)) {
each(cells, (cell, index) => {
if (cell.node === node) {
cellIndex = index;
return false;
}
});
break;
}
node = node.parentElement;
}
return cellIndex;
}

export type ICellTargetArea = 'input' | 'prompt' | 'cell' | 'notebook';

export function detectTargetArea(
cell: Cell,
target: HTMLElement
): ICellTargetArea {
let targetArea: ICellTargetArea = null;
if (cell) {
if (cell.editorWidget.node.contains(event.target as HTMLElement)) {
targetArea = 'input';
} else if (cell.promptNode.contains(event.target as HTMLElement)) {
targetArea = 'prompt';
} else {
targetArea = 'cell';
}
} else {
targetArea = 'notebook';
}
return targetArea;
}

export function shouldStartDrag(
prevX: number,
prevY: number,
nextX: number,
nextY: number
): boolean {
let dx = Math.abs(nextX - prevX);
let dy = Math.abs(nextY - prevY);
return dx >= DRAG_THRESHOLD || dy >= DRAG_THRESHOLD;
}

/**
* Create a cell drag image.
*/
export function createCellDragImage(
activeCell: Cell,
selectedCells: nbformat.ICell[]
): HTMLElement {
const count = selectedCells.length;
let promptNumber: string;
if (activeCell.model.type === 'code') {
let executionCount = (activeCell.model as ICodeCellModel).executionCount;
promptNumber = ' ';
if (executionCount) {
promptNumber = executionCount.toString();
}
} else {
promptNumber = '';
}

const cellContent = activeCell.model.value.text.split('\n')[0].slice(0, 26);
if (count > 1) {
if (promptNumber !== '') {
return VirtualDOM.realize(
h.div(
h.div(
{ className: DRAG_IMAGE_CLASS },
h.span(
{ className: CELL_DRAG_PROMPT_CLASS },
'[' + promptNumber + ']:'
),
h.span({ className: CELL_DRAG_CONTENT_CLASS }, cellContent)
),
h.div({ className: CELL_DRAG_MULTIPLE_BACK }, '')
)
);
} else {
return VirtualDOM.realize(
h.div(
h.div(
{ className: DRAG_IMAGE_CLASS },
h.span({ className: CELL_DRAG_PROMPT_CLASS }),
h.span({ className: CELL_DRAG_CONTENT_CLASS }, cellContent)
),
h.div({ className: CELL_DRAG_MULTIPLE_BACK }, '')
)
);
}
} else {
if (promptNumber !== '') {
return VirtualDOM.realize(
h.div(
h.div(
{ className: `${DRAG_IMAGE_CLASS} ${SINGLE_DRAG_IMAGE_CLASS}` },
h.span(
{ className: CELL_DRAG_PROMPT_CLASS },
'[' + promptNumber + ']:'
),
h.span({ className: CELL_DRAG_CONTENT_CLASS }, cellContent)
)
)
);
} else {
return VirtualDOM.realize(
h.div(
h.div(
{ className: `${DRAG_IMAGE_CLASS} ${SINGLE_DRAG_IMAGE_CLASS}` },
h.span({ className: CELL_DRAG_PROMPT_CLASS }),
h.span({ className: CELL_DRAG_CONTENT_CLASS }, cellContent)
)
)
);
}
}
}
}
1 change: 1 addition & 0 deletions packages/cells/src/index.ts
Expand Up @@ -5,6 +5,7 @@

import '../style/index.css';

export * from './cellDragUtils';
export * from './collapser';
export * from './headerfooter';
export * from './inputarea';
Expand Down
1 change: 1 addition & 0 deletions packages/console/package.json
Expand Up @@ -41,6 +41,7 @@
"@phosphor/algorithm": "^1.1.2",
"@phosphor/coreutils": "^1.3.0",
"@phosphor/disposable": "^1.1.2",
"@phosphor/dragdrop": "^1.3.0",
"@phosphor/messaging": "^1.2.2",
"@phosphor/signaling": "^1.2.2",
"@phosphor/widgets": "^1.6.0"
Expand Down

0 comments on commit 1123548

Please sign in to comment.