Files
azuredatastudio/src/vs/base/browser/ui/button/button.ts
Karl Burtram dafb780987 Merge VS Code 1.21 source code (#1067)
* Initial VS Code 1.21 file copy with patches

* A few more merges

* Post npm install

* Fix batch of build breaks

* Fix more build breaks

* Fix more build errors

* Fix more build breaks

* Runtime fixes 1

* Get connection dialog working with some todos

* Fix a few packaging issues

* Copy several node_modules to package build to fix loader issues

* Fix breaks from master

* A few more fixes

* Make tests pass

* First pass of license header updates

* Second pass of license header updates

* Fix restore dialog issues

* Remove add additional themes menu items

* fix select box issues where the list doesn't show up

* formatting

* Fix editor dispose issue

* Copy over node modules to correct location on all platforms
2018-04-04 15:27:51 -07:00

248 lines
7.0 KiB
TypeScript

/*---------------------------------------------------------------------------------------------
* 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!./button';
import DOM = require('vs/base/browser/dom');
import { Builder, $ } from 'vs/base/browser/builder';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { KeyCode } from 'vs/base/common/keyCodes';
import { Color } from 'vs/base/common/color';
import { mixin } from 'vs/base/common/objects';
import Event, { Emitter } from 'vs/base/common/event';
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
export interface IButtonOptions extends IButtonStyles {
title?: boolean;
}
export interface IButtonStyles {
buttonBackground?: Color;
buttonHoverBackground?: Color;
buttonForeground?: Color;
buttonBorder?: Color;
}
const defaultOptions: IButtonStyles = {
buttonBackground: Color.fromHex('#0E639C'),
buttonHoverBackground: Color.fromHex('#006BB3'),
buttonForeground: Color.white
};
export class Button {
// {{SQL CARBON EDIT}} -- changed access modifier to protected
protected $el: Builder;
private options: IButtonOptions;
private buttonBackground: Color;
private buttonHoverBackground: Color;
private buttonForeground: Color;
private buttonBorder: Color;
private _onDidClick = new Emitter<any>();
readonly onDidClick: Event<any> = this._onDidClick.event;
private focusTracker: DOM.IFocusTracker;
constructor(container: Builder, options?: IButtonOptions);
constructor(container: HTMLElement, options?: IButtonOptions);
constructor(container: any, options?: IButtonOptions) {
this.options = options || Object.create(null);
mixin(this.options, defaultOptions, false);
this.buttonBackground = this.options.buttonBackground;
this.buttonHoverBackground = this.options.buttonHoverBackground;
this.buttonForeground = this.options.buttonForeground;
this.buttonBorder = this.options.buttonBorder;
this.$el = $('a.monaco-button').attr({
'tabIndex': '0',
'role': 'button'
}).appendTo(container);
this.$el.on(DOM.EventType.CLICK, e => {
if (!this.enabled) {
DOM.EventHelper.stop(e);
return;
}
this._onDidClick.fire(e);
});
this.$el.on(DOM.EventType.KEY_DOWN, e => {
let event = new StandardKeyboardEvent(e as KeyboardEvent);
let eventHandled = false;
if (this.enabled && event.equals(KeyCode.Enter) || event.equals(KeyCode.Space)) {
this._onDidClick.fire(e);
eventHandled = true;
} else if (event.equals(KeyCode.Escape)) {
this.$el.domBlur();
eventHandled = true;
}
if (eventHandled) {
DOM.EventHelper.stop(event, true);
}
});
this.$el.on(DOM.EventType.MOUSE_OVER, e => {
if (!this.$el.hasClass('disabled')) {
this.setHoverBackground();
}
});
this.$el.on(DOM.EventType.MOUSE_OUT, e => {
this.applyStyles(); // restore standard styles
});
// Also set hover background when button is focused for feedback
this.focusTracker = DOM.trackFocus(this.$el.getHTMLElement());
this.focusTracker.onDidFocus(() => this.setHoverBackground());
this.focusTracker.onDidBlur(() => this.applyStyles()); // restore standard styles
this.applyStyles();
}
private setHoverBackground(): void {
const hoverBackground = this.buttonHoverBackground ? this.buttonHoverBackground.toString() : null;
if (hoverBackground) {
this.$el.style('background-color', hoverBackground);
}
}
style(styles: IButtonStyles): void {
this.buttonForeground = styles.buttonForeground;
this.buttonBackground = styles.buttonBackground;
this.buttonHoverBackground = styles.buttonHoverBackground;
this.buttonBorder = styles.buttonBorder;
this.applyStyles();
}
// {{SQL CARBON EDIT}} -- removed 'private' access modifier
applyStyles(): void {
if (this.$el) {
const background = this.buttonBackground ? this.buttonBackground.toString() : null;
const foreground = this.buttonForeground ? this.buttonForeground.toString() : null;
const border = this.buttonBorder ? this.buttonBorder.toString() : null;
this.$el.style('color', foreground);
this.$el.style('background-color', background);
this.$el.style('border-width', border ? '1px' : null);
this.$el.style('border-style', border ? 'solid' : null);
this.$el.style('border-color', border);
}
}
get element(): HTMLElement {
return this.$el.getHTMLElement();
}
set label(value: string) {
if (!this.$el.hasClass('monaco-text-button')) {
this.$el.addClass('monaco-text-button');
}
this.$el.text(value);
if (this.options.title) {
this.$el.title(value);
}
}
set icon(iconClassName: string) {
this.$el.addClass(iconClassName);
}
set enabled(value: boolean) {
if (value) {
this.$el.removeClass('disabled');
this.$el.attr({
'aria-disabled': 'false',
'tabIndex': '0'
});
} else {
this.$el.addClass('disabled');
this.$el.attr('aria-disabled', String(true));
DOM.removeTabIndexAndUpdateFocus(this.$el.getHTMLElement());
}
}
get enabled() {
return !this.$el.hasClass('disabled');
}
focus(): void {
this.$el.domFocus();
}
dispose(): void {
if (this.$el) {
this.$el.dispose();
this.$el = null;
this.focusTracker.dispose();
this.focusTracker = null;
}
this._onDidClick.dispose();
}
}
export class ButtonGroup {
private _buttons: Button[];
private toDispose: IDisposable[];
constructor(container: Builder, count: number, options?: IButtonOptions);
constructor(container: HTMLElement, count: number, options?: IButtonOptions);
constructor(container: any, count: number, options?: IButtonOptions) {
this._buttons = [];
this.toDispose = [];
this.create(container, count, options);
}
get buttons(): Button[] {
return this._buttons;
}
private create(container: Builder, count: number, options?: IButtonOptions): void;
private create(container: HTMLElement, count: number, options?: IButtonOptions): void;
private create(container: any, count: number, options?: IButtonOptions): void {
for (let index = 0; index < count; index++) {
const button = new Button(container, options);
this._buttons.push(button);
this.toDispose.push(button);
// Implement keyboard access in buttons if there are multiple
if (count > 1) {
$(button.element).on(DOM.EventType.KEY_DOWN, e => {
const event = new StandardKeyboardEvent(e as KeyboardEvent);
let eventHandled = true;
// Next / Previous Button
let buttonIndexToFocus: number;
if (event.equals(KeyCode.LeftArrow)) {
buttonIndexToFocus = index > 0 ? index - 1 : this._buttons.length - 1;
} else if (event.equals(KeyCode.RightArrow)) {
buttonIndexToFocus = index === this._buttons.length - 1 ? 0 : index + 1;
} else {
eventHandled = false;
}
if (eventHandled) {
this._buttons[buttonIndexToFocus].focus();
DOM.EventHelper.stop(e, true);
}
}, this.toDispose);
}
}
}
dispose(): void {
this.toDispose = dispose(this.toDispose);
}
}