mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-16 17:22:29 -05:00
fix dragging (#2438)
This commit is contained in:
130
src/sql/base/browser/ui/table/plugins/cellRangeSelector.ts
Normal file
130
src/sql/base/browser/ui/table/plugins/cellRangeSelector.ts
Normal file
@@ -0,0 +1,130 @@
|
||||
import { mixin } from 'vs/base/common/objects';
|
||||
|
||||
require.__$__nodeRequire('slickgrid/plugins/slick.cellrangedecorator');
|
||||
|
||||
const defaultOptions: ICellRangeSelectorOptions = {
|
||||
selectionCss: {
|
||||
'border': '2px dashed blue'
|
||||
}
|
||||
};
|
||||
|
||||
export interface ICellRangeSelectorOptions {
|
||||
selectionCss?: { [key: string]: string };
|
||||
cellDecorator?: ICellRangeDecorator;
|
||||
}
|
||||
|
||||
export interface ICellRangeSelector<T> extends Slick.Plugin<T> {
|
||||
onCellRangeSelected: Slick.Event<{ range: Slick.Range }>;
|
||||
onBeforeCellRangeSelected: Slick.Event<Slick.Cell>;
|
||||
}
|
||||
|
||||
export interface ICellRangeDecorator {
|
||||
show(range: Slick.Range);
|
||||
hide();
|
||||
}
|
||||
|
||||
export class CellRangeSelector<T> implements ICellRangeSelector<T> {
|
||||
private grid: Slick.Grid<T>;
|
||||
private dragging: boolean;
|
||||
private handler = new Slick.EventHandler();
|
||||
private decorator: ICellRangeDecorator;
|
||||
private canvas: HTMLCanvasElement;
|
||||
private currentlySelectedRange: { start: Slick.Cell, end: Slick.Cell };
|
||||
|
||||
public onBeforeCellRangeSelected = new Slick.Event<Slick.Cell>();
|
||||
public onCellRangeSelected = new Slick.Event<{ range: Slick.Range }>();
|
||||
|
||||
constructor(private options: ICellRangeSelectorOptions) {
|
||||
this.options = mixin(this.options, defaultOptions, false);
|
||||
}
|
||||
|
||||
public init(grid: Slick.Grid<T>) {
|
||||
this.decorator = this.options.cellDecorator || new (<any>Slick).CellRangeDecorator(grid, this.options);
|
||||
this.grid = grid;
|
||||
this.canvas = this.grid.getCanvasNode();
|
||||
this.handler
|
||||
.subscribe(this.grid.onDragInit, e => this.handleDragInit(e))
|
||||
.subscribe(this.grid.onDragStart, (e, dd) => this.handleDragStart(e, dd))
|
||||
.subscribe(this.grid.onDrag, (e, dd) => this.handleDrag(e, dd))
|
||||
.subscribe(this.grid.onDragEnd, (e, dd) => this.handleDragEnd(e, dd));
|
||||
}
|
||||
|
||||
public destroy() {
|
||||
this.handler.unsubscribeAll();
|
||||
}
|
||||
|
||||
public getCellDecorator() {
|
||||
return this.decorator;
|
||||
}
|
||||
|
||||
public getCurrentRange() {
|
||||
return this.currentlySelectedRange;
|
||||
}
|
||||
|
||||
private handleDragInit(e: DOMEvent) {
|
||||
// prevent the grid from cancelling drag'n'drop by default
|
||||
e.stopImmediatePropagation();
|
||||
}
|
||||
|
||||
private handleDragStart(e: MouseEvent, dd: Slick.OnDragStartEventArgs<T>) {
|
||||
let cell = this.grid.getCellFromEvent(e);
|
||||
if (this.onBeforeCellRangeSelected.notify(cell) !== false) {
|
||||
if (this.grid.canCellBeSelected(cell.row, cell.cell)) {
|
||||
this.dragging = true;
|
||||
e.stopImmediatePropagation();
|
||||
}
|
||||
}
|
||||
if (!this.dragging) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.grid.focus();
|
||||
|
||||
let start = this.grid.getCellFromPoint(
|
||||
dd.startX - $(this.canvas).offset().left,
|
||||
dd.startY - $(this.canvas).offset().top);
|
||||
|
||||
dd.range = { start: start, end: undefined };
|
||||
this.currentlySelectedRange = dd.range;
|
||||
return this.decorator.show(new Slick.Range(start.row, start.cell));
|
||||
}
|
||||
|
||||
private handleDrag(e: MouseEvent, dd: Slick.OnDragEventArgs<T>) {
|
||||
if (!this.dragging) {
|
||||
return;
|
||||
}
|
||||
|
||||
e.stopImmediatePropagation();
|
||||
|
||||
let end = this.grid.getCellFromPoint(
|
||||
e.pageX - $(this.canvas).offset().left,
|
||||
e.pageY - $(this.canvas).offset().top);
|
||||
|
||||
if (!this.grid.canCellBeSelected(end.row, end.cell)) {
|
||||
return;
|
||||
}
|
||||
|
||||
dd.range.end = end;
|
||||
this.currentlySelectedRange = dd.range;
|
||||
this.decorator.show(new Slick.Range(dd.range.start.row, dd.range.start.cell, end.row, end.cell));
|
||||
}
|
||||
|
||||
private handleDragEnd(e: MouseEvent, dd: Slick.OnDragEndEventArgs<T>) {
|
||||
if (!this.dragging) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.dragging = false;
|
||||
e.stopImmediatePropagation();
|
||||
|
||||
this.decorator.hide();
|
||||
this.onCellRangeSelected.notify({
|
||||
range: new Slick.Range(
|
||||
dd.range.start.row,
|
||||
dd.range.start.cell,
|
||||
dd.range.end.row,
|
||||
dd.range.end.cell
|
||||
)
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -3,15 +3,10 @@
|
||||
|
||||
import { mixin } from 'vs/base/common/objects';
|
||||
import { isUndefinedOrNull } from 'vs/base/common/types';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
|
||||
import { CellRangeSelector, ICellRangeSelector } from 'sql/base/browser/ui/table/plugins/cellRangeSelector';
|
||||
|
||||
require.__$__nodeRequire('slickgrid/plugins/slick.cellrangedecorator');
|
||||
require.__$__nodeRequire('slickgrid/plugins/slick.cellrangeselector');
|
||||
|
||||
export interface ICellRangeSelector<T> extends Slick.Plugin<T> {
|
||||
onCellRangeSelected: Slick.Event<{ range: Slick.Range }>;
|
||||
onBeforeCellRangeSelected: Slick.Event<Slick.Cell>;
|
||||
}
|
||||
|
||||
export interface ICellSelectionModelOptions {
|
||||
cellRangeSelector?: any;
|
||||
@@ -36,7 +31,7 @@ export class CellSelectionModel<T> implements Slick.SelectionModel<T, Array<Slic
|
||||
this.selector = this.options.cellRangeSelector;
|
||||
} else {
|
||||
// this is added by the noderequires above
|
||||
this.selector = new (<any>Slick).CellRangeSelector({ selectionCss: { 'border': '2px dashed grey' } });
|
||||
this.selector = new CellRangeSelector({ selectionCss: { 'border': '2px dashed grey' } });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user