You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

238 lines
7.5 KiB

// Select cells with a rubberband-selection using the mouse
// shift + mouse drag -> select only cells currently touched by rubberband
// alt+shift + mouse drag -> select all cells that were touched by rubberband
define([
'base/js/namespace',
'jquery',
'base/js/events',
'base/js/keyboard',
'require'
], function(IPython, $, events, keyboard, requirejs) {
"use strict";
var scrollRange = 50; /* range on top and bottom where autoscroll starts */
var keycodes = keyboard.keycodes;
var startX, startY;
var offsetY;
var isDragging = false;
var isRubberBandEnabled = false;
var isAddSelection = false;
var isScrolling = false;
var headerHeight;
/*
* Test if a cell touched by a certain area
*
* @method isCellWithin
* @param cell
* @param left
* @param top
* @param width
* @param height
*
*/
var isCellWithin = function(cell,left,top,width,height){
var cellpos = cell.element.position();
var cellh = cell.element.height();
var cellw = cell.element.width();
if (cellpos.top === 0)
return false; // not visible
return ((cellpos.top+cellh) > top-offsetY && cellpos.top < top-offsetY+height
&& cellpos.left+cellw > left && cellpos.left < left+width);
};
/**
* load css file and append to document
*
* @method load_css
* @param name {String} filenaame of CSS file
*
*/
var load_css = function (name) {
var link = document.createElement("link");
link.type = "text/css";
link.rel = "stylesheet";
link.href = requirejs.toUrl(name);
document.getElementsByTagName("head")[0].appendChild(link);
};
/**
* Clear existing selection
*
* @method clearSelection
*
*/
var clearSelection = function() {
var ncells = IPython.notebook.ncells();
var cells = IPython.notebook.get_cells();
for(var i=0; i < ncells; i++){
cells[i].unselect();
}
};
function load_ipython_extension() {
/*
* Capture shift key - shift+mouse button will start rubberband selection
*
*/
$(document).keydown(function(event){
if(event.keyCode === keycodes.shift && IPython.notebook.mode === "command"){
isRubberBandEnabled = true
}
if(event.keyCode === keycodes.alt){
isAddSelection = true
}
});
$(document).keyup(function(event){
if(event.keyCode === keycodes.shift){
isRubberBandEnabled = false
}
if(event.keyCode === keycodes.alt){
isAddSelection = false
}
});
/*
* Start rubberband selection action
*
*/
$(document).mousedown(function(event){
offsetY = $('#notebook').offset().top;
headerHeight = $('#header').height();
if(isRubberBandEnabled) {
startX = event.pageX;
startY = event.pageY;
isDragging = true;
$("#dragmask").css(
{
'left' : startX,
'top' : startY,
'width' : 0,
'height' : 0
}
).show();
// prevent default behaviour of text selection
return false;
} else {
if (event.pageY-offsetY > 0) {
/* clear selection */
var ncells = IPython.notebook.ncells();
var cells = IPython.notebook.get_cells();
var selected_idx = IPython.notebook.get_selected_index();
for(var i=0; i < ncells; i++){
if (i != selected_idx) cells[i].unselect();
}
}
}
});
/*
* Rubberband dragging operation - select cells touched by rubberband
*
*/
$(document).mousemove(function(event){
offsetY = $('#notebook').offset().top;
if(isDragging === true){
var left, top, width, height;
if(event.pageX>startX){
left = startX;
width = event.pageX - startX;
}
else {
left = event.pageX;
width = startX - event.pageX;
}
if(event.pageY>startY){
top = startY;
height = event.pageY - startY;
}
else {
top = event.pageY;
height = startY - event.pageY;
}
var ncells = IPython.notebook.ncells();
var cells = IPython.notebook.get_cells();
var elheight = IPython.notebook.scroll_manager.element.height();
var Yfromtop = event.clientY - headerHeight;
var scrollpos = IPython.notebook.scroll_manager.element.scrollTop();
var scrolltime = 200;
if (Yfromtop < scrollRange && isScrolling === false) {
isScrolling = true;
IPython.notebook.scroll_manager.element.animate({scrollTop:scrollpos - 0.3*elheight}, scrolltime,"linear", function() { isScrolling = false })
}
if ( Yfromtop > elheight-scrollRange && isScrolling === false) {
isScrolling = true;
IPython.notebook.scroll_manager.element.animate({scrollTop: scrollpos + 0.3*elheight}, scrolltime,"linear", function() { isScrolling = false })
}
var selected_cells = IPython.notebook.get_selected_cells_indices()
var first = true;
for (var i=0; i<ncells; i++) {
var _cell = cells[i];
if (isCellWithin(_cell,left,top,width,height) === true) {
if (selected_cells.includes(i) == true) first = false;
if (first === true) {
first = false;
IPython.notebook.select(i);
} else {
if (!selected_cells.includes(i)) {
IPython.notebook.select(i, false);
};
};
} else {
if (selected_cells.includes(i)) {
var index = IPython.notebook.get_selected_index();
if (isAddSelection === false) {
var delta = 0;
if (index > i) delta = 1;
if (index < i) delta = -1;
IPython.notebook.select(i+delta, false);
};
}
}
}
$("#dragmask").css(
{
'left' : left,
'top' : top,
'width' : width,
'height' : height
}
)
}
});
/*
* End rubberband dragging operation
*
*/
$(document).mouseup(function(event){
if(isDragging){
isDragging = false;
$("#dragmask").hide();
}
});
load_css('./main.css');
var rubberband_div = $('<div id="dragmask" class="highlight-drag"></div>');
$("#header").append(rubberband_div);
}
/* expose functions to other extensions */
var rubberband = {
load_ipython_extension : load_ipython_extension,
};
return rubberband;
});