mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-03-20 20:10:11 -04:00
SQL Operations Studio Public Preview 1 (0.23) release source code
This commit is contained in:
28
src/vs/editor/contrib/dnd/browser/dnd.css
Normal file
28
src/vs/editor/contrib/dnd/browser/dnd.css
Normal file
@@ -0,0 +1,28 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
.monaco-editor.vs .dnd-target {
|
||||
border-right: 2px dotted black;
|
||||
color: white; /* opposite of black */
|
||||
}
|
||||
.monaco-editor.vs-dark .dnd-target {
|
||||
border-right: 2px dotted #AEAFAD;
|
||||
color: #51504f; /* opposite of #AEAFAD */
|
||||
}
|
||||
.monaco-editor.hc-black .dnd-target {
|
||||
border-right: 2px dotted #fff;
|
||||
color: #000; /* opposite of #fff */
|
||||
}
|
||||
|
||||
.monaco-editor.mouse-default .view-lines,
|
||||
.monaco-editor.vs-dark.mac.mouse-default .view-lines,
|
||||
.monaco-editor.hc-black.mac.mouse-default .view-lines {
|
||||
cursor: default;
|
||||
}
|
||||
.monaco-editor.mouse-copy .view-lines,
|
||||
.monaco-editor.vs-dark.mac.mouse-copy .view-lines,
|
||||
.monaco-editor.hc-black.mac.mouse-copy .view-lines {
|
||||
cursor: copy;
|
||||
}
|
||||
210
src/vs/editor/contrib/dnd/browser/dnd.ts
Normal file
210
src/vs/editor/contrib/dnd/browser/dnd.ts
Normal file
@@ -0,0 +1,210 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import 'vs/css!./dnd';
|
||||
import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { isMacintosh } from 'vs/base/common/platform';
|
||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { ICodeEditor, IEditorMouseEvent, IMouseTarget, MouseTargetType } from 'vs/editor/browser/editorBrowser';
|
||||
import { editorContribution } from 'vs/editor/browser/editorBrowserExtensions';
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { Selection } from 'vs/editor/common/core/selection';
|
||||
import { DragAndDropCommand } from '../common/dragAndDropCommand';
|
||||
import { ModelDecorationOptions } from 'vs/editor/common/model/textModelWithDecorations';
|
||||
|
||||
@editorContribution
|
||||
export class DragAndDropController implements editorCommon.IEditorContribution {
|
||||
|
||||
private static ID = 'editor.contrib.dragAndDrop';
|
||||
|
||||
private _editor: ICodeEditor;
|
||||
private _toUnhook: IDisposable[];
|
||||
private _dragSelection: Selection;
|
||||
private _dndDecorationIds: string[];
|
||||
private _mouseDown: boolean;
|
||||
private _modiferPressed: boolean;
|
||||
static TRIGGER_MODIFIER = isMacintosh ? 'altKey' : 'ctrlKey';
|
||||
static TRIGGER_KEY_VALUE = isMacintosh ? KeyCode.Alt : KeyCode.Ctrl;
|
||||
|
||||
static get(editor: editorCommon.ICommonCodeEditor): DragAndDropController {
|
||||
return editor.getContribution<DragAndDropController>(DragAndDropController.ID);
|
||||
}
|
||||
|
||||
constructor(editor: ICodeEditor) {
|
||||
this._editor = editor;
|
||||
this._toUnhook = [];
|
||||
this._toUnhook.push(this._editor.onMouseDown((e: IEditorMouseEvent) => this._onEditorMouseDown(e)));
|
||||
this._toUnhook.push(this._editor.onMouseUp((e: IEditorMouseEvent) => this._onEditorMouseUp(e)));
|
||||
this._toUnhook.push(this._editor.onMouseDrag((e: IEditorMouseEvent) => this._onEditorMouseDrag(e)));
|
||||
this._toUnhook.push(this._editor.onMouseDrop((e: IEditorMouseEvent) => this._onEditorMouseDrop(e)));
|
||||
this._toUnhook.push(this._editor.onKeyDown((e: IKeyboardEvent) => this.onEditorKeyDown(e)));
|
||||
this._toUnhook.push(this._editor.onKeyUp((e: IKeyboardEvent) => this.onEditorKeyUp(e)));
|
||||
this._dndDecorationIds = [];
|
||||
this._mouseDown = false;
|
||||
this._modiferPressed = false;
|
||||
this._dragSelection = null;
|
||||
}
|
||||
|
||||
private onEditorKeyDown(e: IKeyboardEvent): void {
|
||||
if (!this._editor.getConfiguration().dragAndDrop) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (e[DragAndDropController.TRIGGER_MODIFIER]) {
|
||||
this._modiferPressed = true;
|
||||
}
|
||||
|
||||
if (this._mouseDown && e[DragAndDropController.TRIGGER_MODIFIER]) {
|
||||
this._editor.updateOptions({
|
||||
mouseStyle: 'copy'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private onEditorKeyUp(e: IKeyboardEvent): void {
|
||||
if (!this._editor.getConfiguration().dragAndDrop) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (e[DragAndDropController.TRIGGER_MODIFIER]) {
|
||||
this._modiferPressed = false;
|
||||
}
|
||||
|
||||
if (this._mouseDown && e.keyCode === DragAndDropController.TRIGGER_KEY_VALUE) {
|
||||
this._editor.updateOptions({
|
||||
mouseStyle: 'default'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private _onEditorMouseDown(mouseEvent: IEditorMouseEvent): void {
|
||||
this._mouseDown = true;
|
||||
}
|
||||
|
||||
private _onEditorMouseUp(mouseEvent: IEditorMouseEvent): void {
|
||||
this._mouseDown = false;
|
||||
// Whenever users release the mouse, the drag and drop operation should finish and the cursor should revert to text.
|
||||
this._editor.updateOptions({
|
||||
mouseStyle: 'text'
|
||||
});
|
||||
}
|
||||
|
||||
private _onEditorMouseDrag(mouseEvent: IEditorMouseEvent): void {
|
||||
let target = mouseEvent.target;
|
||||
|
||||
if (this._dragSelection === null) {
|
||||
let possibleSelections = this._editor.getSelections().filter(selection => selection.containsPosition(target.position));
|
||||
if (possibleSelections.length === 1) {
|
||||
this._dragSelection = possibleSelections[0];
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (mouseEvent.event[DragAndDropController.TRIGGER_MODIFIER]) {
|
||||
this._editor.updateOptions({
|
||||
mouseStyle: 'copy'
|
||||
});
|
||||
} else {
|
||||
this._editor.updateOptions({
|
||||
mouseStyle: 'default'
|
||||
});
|
||||
}
|
||||
|
||||
if (this._dragSelection.containsPosition(target.position)) {
|
||||
this._removeDecoration();
|
||||
} else {
|
||||
this.showAt(target.position);
|
||||
}
|
||||
}
|
||||
|
||||
private _onEditorMouseDrop(mouseEvent: IEditorMouseEvent): void {
|
||||
if (mouseEvent.target && (this._hitContent(mouseEvent.target) || this._hitMargin(mouseEvent.target)) && mouseEvent.target.position) {
|
||||
let newCursorPosition = new Position(mouseEvent.target.position.lineNumber, mouseEvent.target.position.column);
|
||||
|
||||
if (this._dragSelection === null) {
|
||||
let newSelections = this._editor.getSelections().map(selection => {
|
||||
if (selection.containsPosition(newCursorPosition)) {
|
||||
return new Selection(newCursorPosition.lineNumber, newCursorPosition.column, newCursorPosition.lineNumber, newCursorPosition.column);
|
||||
} else {
|
||||
return selection;
|
||||
}
|
||||
});
|
||||
this._editor.setSelections(newSelections);
|
||||
} else if (!this._dragSelection.containsPosition(newCursorPosition) ||
|
||||
(
|
||||
(
|
||||
mouseEvent.event[DragAndDropController.TRIGGER_MODIFIER] ||
|
||||
this._modiferPressed
|
||||
) && (
|
||||
this._dragSelection.getEndPosition().equals(newCursorPosition) || this._dragSelection.getStartPosition().equals(newCursorPosition)
|
||||
) // we allow users to paste content beside the selection
|
||||
)) {
|
||||
this._editor.pushUndoStop();
|
||||
this._editor.executeCommand(DragAndDropController.ID, new DragAndDropCommand(this._dragSelection, newCursorPosition, mouseEvent.event[DragAndDropController.TRIGGER_MODIFIER] || this._modiferPressed));
|
||||
this._editor.pushUndoStop();
|
||||
}
|
||||
}
|
||||
|
||||
this._editor.updateOptions({
|
||||
mouseStyle: 'text'
|
||||
});
|
||||
|
||||
this._removeDecoration();
|
||||
this._dragSelection = null;
|
||||
this._mouseDown = false;
|
||||
}
|
||||
|
||||
private static _DECORATION_OPTIONS = ModelDecorationOptions.register({
|
||||
className: 'dnd-target'
|
||||
});
|
||||
|
||||
public showAt(position: Position): void {
|
||||
this._editor.changeDecorations(changeAccessor => {
|
||||
let newDecorations: editorCommon.IModelDeltaDecoration[] = [];
|
||||
newDecorations.push({
|
||||
range: new Range(position.lineNumber, position.column, position.lineNumber, position.column),
|
||||
options: DragAndDropController._DECORATION_OPTIONS
|
||||
});
|
||||
|
||||
this._dndDecorationIds = changeAccessor.deltaDecorations(this._dndDecorationIds, newDecorations);
|
||||
});
|
||||
this._editor.revealPosition(position, editorCommon.ScrollType.Immediate);
|
||||
}
|
||||
|
||||
private _removeDecoration(): void {
|
||||
this._editor.changeDecorations(changeAccessor => {
|
||||
changeAccessor.deltaDecorations(this._dndDecorationIds, []);
|
||||
});
|
||||
}
|
||||
|
||||
private _hitContent(target: IMouseTarget): boolean {
|
||||
return target.type === MouseTargetType.CONTENT_TEXT ||
|
||||
target.type === MouseTargetType.CONTENT_EMPTY;
|
||||
}
|
||||
|
||||
private _hitMargin(target: IMouseTarget): boolean {
|
||||
return target.type === MouseTargetType.GUTTER_GLYPH_MARGIN ||
|
||||
target.type === MouseTargetType.GUTTER_LINE_NUMBERS ||
|
||||
target.type === MouseTargetType.GUTTER_LINE_DECORATIONS;
|
||||
}
|
||||
|
||||
public getId(): string {
|
||||
return DragAndDropController.ID;
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
this._removeDecoration();
|
||||
this._dragSelection = null;
|
||||
this._mouseDown = false;
|
||||
this._modiferPressed = false;
|
||||
this._toUnhook = dispose(this._toUnhook);
|
||||
}
|
||||
}
|
||||
107
src/vs/editor/contrib/dnd/common/dragAndDropCommand.ts
Normal file
107
src/vs/editor/contrib/dnd/common/dragAndDropCommand.ts
Normal file
@@ -0,0 +1,107 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import { Selection } from 'vs/editor/common/core/selection';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
|
||||
|
||||
export class DragAndDropCommand implements editorCommon.ICommand {
|
||||
|
||||
private selection: Selection;
|
||||
private targetPosition: Position;
|
||||
private targetSelection: Selection;
|
||||
private copy: boolean;
|
||||
|
||||
constructor(selection: Selection, targetPosition: Position, copy: boolean) {
|
||||
this.selection = selection;
|
||||
this.targetPosition = targetPosition;
|
||||
this.copy = copy;
|
||||
}
|
||||
|
||||
public getEditOperations(model: editorCommon.ITokenizedModel, builder: editorCommon.IEditOperationBuilder): void {
|
||||
let text = model.getValueInRange(this.selection);
|
||||
if (!this.copy) {
|
||||
builder.addEditOperation(this.selection, null);
|
||||
}
|
||||
builder.addEditOperation(new Range(this.targetPosition.lineNumber, this.targetPosition.column, this.targetPosition.lineNumber, this.targetPosition.column), text);
|
||||
|
||||
if (this.selection.containsPosition(this.targetPosition) && !(
|
||||
this.copy && (
|
||||
this.selection.getEndPosition().equals(this.targetPosition) || this.selection.getStartPosition().equals(this.targetPosition)
|
||||
) // we allow users to paste content beside the selection
|
||||
)) {
|
||||
this.targetSelection = this.selection;
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.copy) {
|
||||
this.targetSelection = new Selection(
|
||||
this.targetPosition.lineNumber,
|
||||
this.targetPosition.column,
|
||||
this.selection.endLineNumber - this.selection.startLineNumber + this.targetPosition.lineNumber,
|
||||
this.selection.startLineNumber === this.selection.endLineNumber ?
|
||||
this.targetPosition.column + this.selection.endColumn - this.selection.startColumn :
|
||||
this.selection.endColumn
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.targetPosition.lineNumber > this.selection.endLineNumber) {
|
||||
// Drag the selection downwards
|
||||
this.targetSelection = new Selection(
|
||||
this.targetPosition.lineNumber - this.selection.endLineNumber + this.selection.startLineNumber,
|
||||
this.targetPosition.column,
|
||||
this.targetPosition.lineNumber,
|
||||
this.selection.startLineNumber === this.selection.endLineNumber ?
|
||||
this.targetPosition.column + this.selection.endColumn - this.selection.startColumn :
|
||||
this.selection.endColumn
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.targetPosition.lineNumber < this.selection.endLineNumber) {
|
||||
// Drag the selection upwards
|
||||
this.targetSelection = new Selection(
|
||||
this.targetPosition.lineNumber,
|
||||
this.targetPosition.column,
|
||||
this.targetPosition.lineNumber + this.selection.endLineNumber - this.selection.startLineNumber,
|
||||
this.selection.startLineNumber === this.selection.endLineNumber ?
|
||||
this.targetPosition.column + this.selection.endColumn - this.selection.startColumn :
|
||||
this.selection.endColumn
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// The target position is at the same line as the selection's end position.
|
||||
if (this.selection.endColumn <= this.targetPosition.column) {
|
||||
// The target position is after the selection's end position
|
||||
this.targetSelection = new Selection(
|
||||
this.targetPosition.lineNumber - this.selection.endLineNumber + this.selection.startLineNumber,
|
||||
this.selection.startLineNumber === this.selection.endLineNumber ?
|
||||
this.targetPosition.column - this.selection.endColumn + this.selection.startColumn :
|
||||
this.targetPosition.column - this.selection.endColumn + this.selection.startColumn,
|
||||
this.targetPosition.lineNumber,
|
||||
this.selection.startLineNumber === this.selection.endLineNumber ?
|
||||
this.targetPosition.column :
|
||||
this.selection.endColumn
|
||||
);
|
||||
} else {
|
||||
// The target position is before the selection's end postion. Since the selection doesn't contain the target position, the selection is one-line and target position is before this selection.
|
||||
this.targetSelection = new Selection(
|
||||
this.targetPosition.lineNumber - this.selection.endLineNumber + this.selection.startLineNumber,
|
||||
this.targetPosition.column,
|
||||
this.targetPosition.lineNumber,
|
||||
this.targetPosition.column + this.selection.endColumn - this.selection.startColumn
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public computeCursorState(model: editorCommon.ITokenizedModel, helper: editorCommon.ICursorStateComputerData): Selection {
|
||||
return this.targetSelection;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user