make alt command behaviour smooth

This commit is contained in:
Johannes Rieken
2016-06-24 18:01:32 +02:00
parent 15addfc4f7
commit 02adcfd63c

View File

@@ -9,8 +9,10 @@ import {localize} from 'vs/nls';
import {IKeybindingService} from 'vs/platform/keybinding/common/keybindingService';
import {IMenu, MenuItemAction} from 'vs/platform/actions/common/actions';
import {IAction} from 'vs/base/common/actions';
import {IDisposable, dispose} from 'vs/base/common/lifecycle';
import {ActionItem, Separator} from 'vs/base/browser/ui/actionbar/actionbar';
import {domEvent} from 'vs/base/browser/event';
import {Emitter} from 'vs/base/common/event';
export function fillInActions(menu: IMenu, target: IAction[] | { primary: IAction[]; secondary: IAction[];}): void {
@@ -44,6 +46,28 @@ export function createActionItem(action: IAction, keybindingService: IKeybinding
}
}
const _altKey = new class extends Emitter<boolean> {
private _subscriptions: IDisposable[] = [];
constructor() {
super({
onFirstListenerAdd: () => {
domEvent(document.body, 'keydown')(this._key, this, this._subscriptions);
domEvent(document.body, 'keyup')(this._key, this, this._subscriptions);
},
onLastListenerRemove: () => {
this._subscriptions = dispose(this._subscriptions);
}
});
}
private _key(e: KeyboardEvent) {
this.fire(e.type === 'keydown' && e.altKey);
}
};
class MenuItemActionItem extends ActionItem {
private _altKeyDown: boolean = false;
@@ -55,7 +79,7 @@ class MenuItemActionItem extends ActionItem {
super(undefined, action, { icon: !!action.command.iconClass, label: !action.command.iconClass });
}
private get command() {
private get _command() {
const {command, altCommand} = <MenuItemAction>this._action;
return this._altKeyDown && altCommand || command;
}
@@ -70,38 +94,45 @@ class MenuItemActionItem extends ActionItem {
render(container: HTMLElement): void {
super.render(container);
this._callOnDispose.push(domEvent(container, 'mousemove')(e => {
if (this._altKeyDown !== e.altKey) {
this._altKeyDown = e.altKey;
let altSubscription: IDisposable;
this._callOnDispose.push(domEvent(container, 'mouseleave')(_ => dispose(altSubscription)));
this._callOnDispose.push(domEvent(container, 'mouseenter')(e => {
altSubscription = _altKey.event(value => {
this._altKeyDown = value;
this._updateLabel();
this._updateTooltip();
this._updateClass();
}
});
}));
}
_updateLabel(): void {
if (this.options.label) {
this.$e.text(this.command.title);
this.$e.text(this._command.title);
}
}
_updateTooltip(): void {
const element = this.$e.getHTMLElement();
const keybinding = this._keybindingService.lookupKeybindings(this.command.id)[0];
const keybinding = this._keybindingService.lookupKeybindings(this._command.id)[0];
const keybindingLabel = keybinding && this._keybindingService.getLabelFor(keybinding);
element.title = keybindingLabel
? localize('titleAndKb', "{0} ({1})", this.command.title, keybindingLabel)
: this.command.title;
? localize('titleAndKb', "{0} ({1})", this._command.title, keybindingLabel)
: this._command.title;
}
_updateClass(): void {
if (this.options.icon) {
const element = this.$e.getHTMLElement();
const {iconClass} = this.command;
element.classList.add('icon', iconClass);
const {command, altCommand} = (<MenuItemAction>this._action);
if (this._command !== command) {
element.classList.remove(command.iconClass);
} else if (altCommand) {
element.classList.remove(altCommand.iconClass);
}
element.classList.add('icon', this._command.iconClass);
}
}
}