提交 9bcb8b18 编写于 作者: A Alex Dima

Merge pull request #8153 from kisstkondoros/cursorstyles

New cursor animation styles implemented
...@@ -416,6 +416,7 @@ export function createMonacoEditorAPI(): typeof monaco.editor { ...@@ -416,6 +416,7 @@ export function createMonacoEditorAPI(): typeof monaco.editor {
CursorChangeReason: editorCommon.CursorChangeReason, CursorChangeReason: editorCommon.CursorChangeReason,
MouseTargetType: editorCommon.MouseTargetType, MouseTargetType: editorCommon.MouseTargetType,
TextEditorCursorStyle: editorCommon.TextEditorCursorStyle, TextEditorCursorStyle: editorCommon.TextEditorCursorStyle,
TextEditorCursorBlinkingStyle: editorCommon.TextEditorCursorBlinkingStyle,
ContentWidgetPositionPreference: ContentWidgetPositionPreference, ContentWidgetPositionPreference: ContentWidgetPositionPreference,
OverlayWidgetPositionPreference: OverlayWidgetPositionPreference, OverlayWidgetPositionPreference: OverlayWidgetPositionPreference,
......
...@@ -46,3 +46,61 @@ ...@@ -46,3 +46,61 @@
border-color: #fff; border-color: #fff;
color: #000; /* opposite of #fff */ color: #000; /* opposite of #fff */
} }
@keyframes cursor-blink {
50% {
opacity: 0;
}
100% {
opacity: 1;
}
}
@keyframes cursor-smooth {
0%,
20% {
opacity: 0;
}
60%,
100% {
opacity: 1;
}
}
@keyframes cursor-phase {
0%,
20% {
opacity: 0;
}
90%,
100% {
opacity: 1;
}
}
@keyframes cursor-expand {
0%,
20% {
transform: scaleY(0);
}
80%,
100% {
transform: scaleY(1);
}
}
.cursor-blink > .cursor {
animation: cursor-blink 1s step-start 0s infinite;
}
.cursor-smooth > .cursor {
animation: cursor-smooth 0.5s ease-in-out 0s infinite alternate;
}
.cursor-phase > .cursor {
animation: cursor-phase 0.5s ease-in-out 0s infinite alternate;
}
.cursor-expand > .cursor {
animation: cursor-expand 0.5s ease-in-out 0s infinite alternate;
}
\ No newline at end of file
...@@ -13,19 +13,17 @@ import {ViewCursor} from 'vs/editor/browser/viewParts/viewCursors/viewCursor'; ...@@ -13,19 +13,17 @@ import {ViewCursor} from 'vs/editor/browser/viewParts/viewCursors/viewCursor';
import {ViewContext} from 'vs/editor/common/view/viewContext'; import {ViewContext} from 'vs/editor/common/view/viewContext';
import {IRenderingContext, IRestrictedRenderingContext} from 'vs/editor/common/view/renderingContext'; import {IRenderingContext, IRestrictedRenderingContext} from 'vs/editor/common/view/renderingContext';
import {FastDomNode, createFastDomNode} from 'vs/base/browser/styleMutator'; import {FastDomNode, createFastDomNode} from 'vs/base/browser/styleMutator';
import {TimeoutTimer, IntervalTimer} from 'vs/base/common/async';
import * as browsers from 'vs/base/browser/browser';
enum RenderType { const ANIMATIONS_SUPPORTED = !browsers.isIE9;
Hidden,
Visible,
Blink
}
export class ViewCursors extends ViewPart { export class ViewCursors extends ViewPart {
static BLINK_INTERVAL = 500; static BLINK_INTERVAL = 500;
private _readOnly: boolean; private _readOnly: boolean;
private _cursorBlinking: string; private _cursorBlinking: editorCommon.TextEditorCursorBlinkingStyle;
private _cursorStyle: editorCommon.TextEditorCursorStyle; private _cursorStyle: editorCommon.TextEditorCursorStyle;
private _canUseTranslate3d: boolean; private _canUseTranslate3d: boolean;
...@@ -33,7 +31,9 @@ export class ViewCursors extends ViewPart { ...@@ -33,7 +31,9 @@ export class ViewCursors extends ViewPart {
private _domNode: FastDomNode; private _domNode: FastDomNode;
private _blinkTimer: number; private _startCursorBlinkAnimation: TimeoutTimer;
private _compatBlink: IntervalTimer;
private _blinkingEnabled: boolean;
private _editorHasFocus: boolean; private _editorHasFocus: boolean;
...@@ -56,7 +56,9 @@ export class ViewCursors extends ViewPart { ...@@ -56,7 +56,9 @@ export class ViewCursors extends ViewPart {
this._domNode.domNode.appendChild(this._primaryCursor.getDomNode()); this._domNode.domNode.appendChild(this._primaryCursor.getDomNode());
this._blinkTimer = -1; this._startCursorBlinkAnimation = new TimeoutTimer();
this._compatBlink = new IntervalTimer();
this._blinkingEnabled = false;
this._editorHasFocus = false; this._editorHasFocus = false;
this._updateBlinking(); this._updateBlinking();
...@@ -64,10 +66,8 @@ export class ViewCursors extends ViewPart { ...@@ -64,10 +66,8 @@ export class ViewCursors extends ViewPart {
public dispose(): void { public dispose(): void {
super.dispose(); super.dispose();
if (this._blinkTimer !== -1) { this._startCursorBlinkAnimation.dispose();
window.clearInterval(this._blinkTimer); this._compatBlink.dispose();
this._blinkTimer = -1;
}
} }
public getDomNode(): HTMLElement { public getDomNode(): HTMLElement {
...@@ -159,7 +159,7 @@ export class ViewCursors extends ViewPart { ...@@ -159,7 +159,7 @@ export class ViewCursors extends ViewPart {
this._primaryCursor.onConfigurationChanged(e); this._primaryCursor.onConfigurationChanged(e);
this._updateBlinking(); this._updateBlinking();
if (e.viewInfo.cursorStyle) { if (e.viewInfo.cursorStyle || e.viewInfo.cursorBlinking) {
this._updateDomClassName(); this._updateDomClassName();
} }
for (var i = 0, len = this._secondaryCursors.length; i < len; i++) { for (var i = 0, len = this._secondaryCursors.length; i < len; i++) {
...@@ -189,41 +189,44 @@ export class ViewCursors extends ViewPart { ...@@ -189,41 +189,44 @@ export class ViewCursors extends ViewPart {
// ---- blinking logic // ---- blinking logic
private _getRenderType(): RenderType { private _getCursorBlinking(): editorCommon.TextEditorCursorBlinkingStyle {
if (this._editorHasFocus) { if (!this._editorHasFocus) {
if (this._primaryCursor.getIsInEditableRange() && !this._readOnly) { return editorCommon.TextEditorCursorBlinkingStyle.Hidden;
switch (this._cursorBlinking) { }
case 'blink': if (this._readOnly || !this._primaryCursor.getIsInEditableRange()) {
return RenderType.Blink; return editorCommon.TextEditorCursorBlinkingStyle.Solid;
case 'visible':
return RenderType.Visible;
case 'hidden':
return RenderType.Hidden;
default:
return RenderType.Blink;
}
}
return RenderType.Visible;
} }
return RenderType.Hidden; return this._cursorBlinking;
} }
private _updateBlinking(): void { private _updateBlinking(): void {
if (this._blinkTimer !== -1) { this._startCursorBlinkAnimation.cancel();
window.clearInterval(this._blinkTimer); this._compatBlink.cancel();
this._blinkTimer = -1;
}
var renderType = this._getRenderType(); let blinkingStyle = this._getCursorBlinking();
if (renderType === RenderType.Visible || renderType === RenderType.Blink) { // hidden and solid are special as they involve no animations
this._show(); let isHidden = (blinkingStyle === editorCommon.TextEditorCursorBlinkingStyle.Hidden);
} else { let isSolid = (blinkingStyle === editorCommon.TextEditorCursorBlinkingStyle.Solid);
if (isHidden) {
this._hide(); this._hide();
} else {
this._show();
} }
if (renderType === RenderType.Blink) { this._blinkingEnabled = false;
this._blinkTimer = window.setInterval(() => this._blink(), ViewCursors.BLINK_INTERVAL); this._updateDomClassName();
if (!isHidden && !isSolid) {
if (ANIMATIONS_SUPPORTED) {
this._startCursorBlinkAnimation.setIfNotSet(() => {
this._blinkingEnabled = true;
this._updateDomClassName();
}, ViewCursors.BLINK_INTERVAL);
} else {
this._compatBlink.cancelAndSet(() => this._compatBlinkUpdate(), ViewCursors.BLINK_INTERVAL);
}
} }
} }
// --- end blinking logic // --- end blinking logic
...@@ -234,24 +237,46 @@ export class ViewCursors extends ViewPart { ...@@ -234,24 +237,46 @@ export class ViewCursors extends ViewPart {
private _getClassName(): string { private _getClassName(): string {
let result = ClassNames.VIEW_CURSORS_LAYER; let result = ClassNames.VIEW_CURSORS_LAYER;
let extraClassName: string;
switch (this._cursorStyle) { switch (this._cursorStyle) {
case editorCommon.TextEditorCursorStyle.Line: case editorCommon.TextEditorCursorStyle.Line:
extraClassName = 'cursor-line-style'; result += ' cursor-line-style';
break; break;
case editorCommon.TextEditorCursorStyle.Block: case editorCommon.TextEditorCursorStyle.Block:
extraClassName = 'cursor-block-style'; result += ' cursor-block-style';
break; break;
case editorCommon.TextEditorCursorStyle.Underline: case editorCommon.TextEditorCursorStyle.Underline:
extraClassName = 'cursor-underline-style'; result += ' cursor-underline-style';
break; break;
default: default:
extraClassName = 'cursor-line-style'; result += ' cursor-line-style';
}
if (this._blinkingEnabled) {
switch (this._getCursorBlinking()) {
case editorCommon.TextEditorCursorBlinkingStyle.Blink:
result += ' cursor-blink';
break;
case editorCommon.TextEditorCursorBlinkingStyle.Smooth:
result += ' cursor-smooth';
break;
case editorCommon.TextEditorCursorBlinkingStyle.Phase:
result += ' cursor-phase';
break;
case editorCommon.TextEditorCursorBlinkingStyle.Expand:
result += ' cursor-expand';
break;
case editorCommon.TextEditorCursorBlinkingStyle.Solid:
result += ' cursor-solid';
break;
default:
result += ' cursor-solid';
}
} else {
result += ' cursor-solid';
} }
return result + ' ' + extraClassName; return result;
} }
private _blink(): void { private _compatBlinkUpdate(): void {
if (this._isVisible) { if (this._isVisible) {
this._hide(); this._hide();
} else { } else {
......
...@@ -237,7 +237,7 @@ class InternalEditorOptionsHelper { ...@@ -237,7 +237,7 @@ class InternalEditorOptionsHelper {
revealHorizontalRightPadding: toInteger(opts.revealHorizontalRightPadding, 0), revealHorizontalRightPadding: toInteger(opts.revealHorizontalRightPadding, 0),
roundedSelection: toBoolean(opts.roundedSelection), roundedSelection: toBoolean(opts.roundedSelection),
overviewRulerLanes: toInteger(opts.overviewRulerLanes, 0, 3), overviewRulerLanes: toInteger(opts.overviewRulerLanes, 0, 3),
cursorBlinking: opts.cursorBlinking, cursorBlinking: cursorBlinkingStyleFromString(opts.cursorBlinking),
mouseWheelZoom: toBoolean(opts.mouseWheelZoom), mouseWheelZoom: toBoolean(opts.mouseWheelZoom),
cursorStyle: cursorStyleFromString(opts.cursorStyle), cursorStyle: cursorStyleFromString(opts.cursorStyle),
hideCursorInOverviewRuler: toBoolean(opts.hideCursorInOverviewRuler), hideCursorInOverviewRuler: toBoolean(opts.hideCursorInOverviewRuler),
...@@ -378,6 +378,23 @@ function cursorStyleFromString(cursorStyle:string): editorCommon.TextEditorCurso ...@@ -378,6 +378,23 @@ function cursorStyleFromString(cursorStyle:string): editorCommon.TextEditorCurso
return editorCommon.TextEditorCursorStyle.Line; return editorCommon.TextEditorCursorStyle.Line;
} }
function cursorBlinkingStyleFromString(cursorBlinkingStyle: string): editorCommon.TextEditorCursorBlinkingStyle {
switch (cursorBlinkingStyle) {
case 'blink':
return editorCommon.TextEditorCursorBlinkingStyle.Blink;
case 'smooth':
return editorCommon.TextEditorCursorBlinkingStyle.Smooth;
case 'phase':
return editorCommon.TextEditorCursorBlinkingStyle.Phase;
case 'expand':
return editorCommon.TextEditorCursorBlinkingStyle.Expand;
case 'visible': // maintain compatibility
case 'solid':
return editorCommon.TextEditorCursorBlinkingStyle.Solid;
}
return editorCommon.TextEditorCursorBlinkingStyle.Blink;
}
function toIntegerWithDefault(source:any, defaultValue:number): number { function toIntegerWithDefault(source:any, defaultValue:number): number {
if (typeof source === 'undefined') { if (typeof source === 'undefined') {
return defaultValue; return defaultValue;
...@@ -702,9 +719,9 @@ let editorConfiguration:IConfigurationNode = { ...@@ -702,9 +719,9 @@ let editorConfiguration:IConfigurationNode = {
}, },
'editor.cursorBlinking' : { 'editor.cursorBlinking' : {
'type': 'string', 'type': 'string',
'enum': ['blink', 'visible', 'hidden'], 'enum': ['blink', 'smooth', 'phase', 'expand', 'solid'],
'default': DefaultConfig.editor.cursorBlinking, 'default': DefaultConfig.editor.cursorBlinking,
'description': nls.localize('cursorBlinking', "Controls the cursor blinking animation, accepted values are 'blink', 'visible', and 'hidden'") 'description': nls.localize('cursorBlinking', "Control the cursor animation style, possible values are 'blink', 'smooth', 'phase', 'expand' and 'solid'")
}, },
'editor.mouseWheelZoom': { 'editor.mouseWheelZoom': {
'type': 'boolean', 'type': 'boolean',
......
...@@ -259,7 +259,7 @@ export interface IEditorOptions { ...@@ -259,7 +259,7 @@ export interface IEditorOptions {
*/ */
overviewRulerLanes?:number; overviewRulerLanes?:number;
/** /**
* Control the cursor blinking animation. * Control the cursor animation style, possible values are 'blink', 'smooth', 'phase', 'expand' and 'solid'.
* Defaults to 'blink'. * Defaults to 'blink'.
*/ */
cursorBlinking?:string; cursorBlinking?:string;
...@@ -602,7 +602,7 @@ export class InternalEditorViewOptions { ...@@ -602,7 +602,7 @@ export class InternalEditorViewOptions {
revealHorizontalRightPadding:number; revealHorizontalRightPadding:number;
roundedSelection:boolean; roundedSelection:boolean;
overviewRulerLanes:number; overviewRulerLanes:number;
cursorBlinking:string; cursorBlinking:TextEditorCursorBlinkingStyle;
mouseWheelZoom:boolean; mouseWheelZoom:boolean;
cursorStyle:TextEditorCursorStyle; cursorStyle:TextEditorCursorStyle;
hideCursorInOverviewRuler:boolean; hideCursorInOverviewRuler:boolean;
...@@ -629,7 +629,7 @@ export class InternalEditorViewOptions { ...@@ -629,7 +629,7 @@ export class InternalEditorViewOptions {
revealHorizontalRightPadding:number; revealHorizontalRightPadding:number;
roundedSelection:boolean; roundedSelection:boolean;
overviewRulerLanes:number; overviewRulerLanes:number;
cursorBlinking:string; cursorBlinking:TextEditorCursorBlinkingStyle;
mouseWheelZoom:boolean; mouseWheelZoom:boolean;
cursorStyle:TextEditorCursorStyle; cursorStyle:TextEditorCursorStyle;
hideCursorInOverviewRuler:boolean; hideCursorInOverviewRuler:boolean;
...@@ -652,7 +652,7 @@ export class InternalEditorViewOptions { ...@@ -652,7 +652,7 @@ export class InternalEditorViewOptions {
this.revealHorizontalRightPadding = source.revealHorizontalRightPadding|0; this.revealHorizontalRightPadding = source.revealHorizontalRightPadding|0;
this.roundedSelection = Boolean(source.roundedSelection); this.roundedSelection = Boolean(source.roundedSelection);
this.overviewRulerLanes = source.overviewRulerLanes|0; this.overviewRulerLanes = source.overviewRulerLanes|0;
this.cursorBlinking = String(source.cursorBlinking); this.cursorBlinking = source.cursorBlinking|0;
this.mouseWheelZoom = Boolean(source.mouseWheelZoom); this.mouseWheelZoom = Boolean(source.mouseWheelZoom);
this.cursorStyle = source.cursorStyle|0; this.cursorStyle = source.cursorStyle|0;
this.hideCursorInOverviewRuler = Boolean(source.hideCursorInOverviewRuler); this.hideCursorInOverviewRuler = Boolean(source.hideCursorInOverviewRuler);
...@@ -4262,6 +4262,36 @@ export enum TextEditorCursorStyle { ...@@ -4262,6 +4262,36 @@ export enum TextEditorCursorStyle {
Underline = 3 Underline = 3
} }
/**
* The kind of animation in which the editor's cursor should be rendered.
*/
export enum TextEditorCursorBlinkingStyle {
/**
* Hidden
*/
Hidden = 0,
/**
* Blinking
*/
Blink = 1,
/**
* Blinking with smooth fading
*/
Smooth = 2,
/**
* Blinking with prolonged filled state and smooth fading
*/
Phase = 3,
/**
* Expand collapse animation on the y axis
*/
Expand = 4,
/**
* No-Blinking
*/
Solid = 5
}
/** /**
* @internal * @internal
*/ */
......
...@@ -1113,7 +1113,7 @@ declare module monaco.editor { ...@@ -1113,7 +1113,7 @@ declare module monaco.editor {
*/ */
overviewRulerLanes?: number; overviewRulerLanes?: number;
/** /**
* Control the cursor blinking animation. * Control the cursor animation style, possible values are 'blink', 'smooth', 'phase', 'expand' and 'solid'.
* Defaults to 'blink'. * Defaults to 'blink'.
*/ */
cursorBlinking?: string; cursorBlinking?: string;
...@@ -1354,7 +1354,7 @@ declare module monaco.editor { ...@@ -1354,7 +1354,7 @@ declare module monaco.editor {
revealHorizontalRightPadding: number; revealHorizontalRightPadding: number;
roundedSelection: boolean; roundedSelection: boolean;
overviewRulerLanes: number; overviewRulerLanes: number;
cursorBlinking: string; cursorBlinking: TextEditorCursorBlinkingStyle;
mouseWheelZoom: boolean; mouseWheelZoom: boolean;
cursorStyle: TextEditorCursorStyle; cursorStyle: TextEditorCursorStyle;
hideCursorInOverviewRuler: boolean; hideCursorInOverviewRuler: boolean;
...@@ -3304,6 +3304,36 @@ declare module monaco.editor { ...@@ -3304,6 +3304,36 @@ declare module monaco.editor {
Underline = 3, Underline = 3,
} }
/**
* The kind of animation in which the editor's cursor should be rendered.
*/
export enum TextEditorCursorBlinkingStyle {
/**
* Hidden
*/
Hidden = 0,
/**
* Blinking
*/
Blink = 1,
/**
* Blinking with smooth fading
*/
Smooth = 2,
/**
* Blinking with prolonged filled state and smooth fading
*/
Phase = 3,
/**
* Expand collapse animation on the y axis
*/
Expand = 4,
/**
* No-Blinking
*/
Solid = 5,
}
/** /**
* A view zone is a full horizontal rectangle that 'pushes' text down. * A view zone is a full horizontal rectangle that 'pushes' text down.
* The editor reserves space for view zones when rendering. * The editor reserves space for view zones when rendering.
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册