theming - keybindings button and widget

This commit is contained in:
Benjamin Pasero 2017-05-08 19:44:35 +02:00
parent a7c753cf40
commit 408ede050d
5 changed files with 60 additions and 39 deletions

View file

@ -10,11 +10,13 @@ import { inputBackground, inputForeground, ColorIdentifier, selectForeground, se
import { IDisposable } from 'vs/base/common/lifecycle';
import { SIDE_BAR_SECTION_HEADER_BACKGROUND } from 'vs/workbench/common/theme';
export type styleFn = (colors: { [name: string]: ColorIdentifier }) => void;
export interface IThemable {
style(colors: { [name: string]: ColorIdentifier }): void;
style: styleFn;
}
export function attachStyler(themeService: IThemeService, widget: IThemable, optionsMapping: { [optionsKey: string]: ColorIdentifier | ColorFunction }): IDisposable {
function doAttachStyler(themeService: IThemeService, optionsMapping: { [optionsKey: string]: ColorIdentifier | ColorFunction }, widgetOrCallback: IThemable | styleFn): IDisposable {
function applyStyles(theme: ITheme): void {
const styles = Object.create(null);
for (let key in optionsMapping) {
@ -26,7 +28,11 @@ export function attachStyler(themeService: IThemeService, widget: IThemable, opt
}
}
widget.style(styles);
if (typeof widgetOrCallback === 'function') {
widgetOrCallback(styles);
} else {
widgetOrCallback.style(styles);
}
}
applyStyles(themeService.getTheme());
@ -35,9 +41,9 @@ export function attachStyler(themeService: IThemeService, widget: IThemable, opt
}
export function attachCheckboxStyler(widget: IThemable, themeService: IThemeService, style?: { inputActiveOptionBorderColor?: ColorIdentifier }): IDisposable {
return attachStyler(themeService, widget, {
return doAttachStyler(themeService, {
inputActiveOptionBorder: (style && style.inputActiveOptionBorderColor) || inputActiveOptionBorder
});
}, widget);
}
export function attachInputBoxStyler(widget: IThemable, themeService: IThemeService, style?:
@ -52,7 +58,7 @@ export function attachInputBoxStyler(widget: IThemable, themeService: IThemeServ
inputValidationErrorBorder?: ColorIdentifier,
inputValidationErrorBackground?: ColorIdentifier
}): IDisposable {
return attachStyler(themeService, widget, {
return doAttachStyler(themeService, {
inputBackground: (style && style.inputBackground) || inputBackground,
inputForeground: (style && style.inputForeground) || inputForeground,
inputBorder: (style && style.inputBorder) || inputBorder,
@ -62,15 +68,15 @@ export function attachInputBoxStyler(widget: IThemable, themeService: IThemeServ
inputValidationWarningBackground: (style && style.inputValidationWarningBackground) || inputValidationWarningBackground,
inputValidationErrorBorder: (style && style.inputValidationErrorBorder) || inputValidationErrorBorder,
inputValidationErrorBackground: (style && style.inputValidationErrorBackground) || inputValidationErrorBackground
});
}, widget);
}
export function attachSelectBoxStyler(widget: IThemable, themeService: IThemeService, style?: { selectBackground?: ColorIdentifier, selectForeground?: ColorIdentifier, selectBorder?: ColorIdentifier }): IDisposable {
return attachStyler(themeService, widget, {
return doAttachStyler(themeService, {
selectBackground: (style && style.selectBackground) || selectBackground,
selectForeground: (style && style.selectForeground) || selectForeground,
selectBorder: (style && style.selectBorder) || selectBorder
});
}, widget);
}
export function attachFindInputBoxStyler(widget: IThemable, themeService: IThemeService, style?:
@ -86,7 +92,7 @@ export function attachFindInputBoxStyler(widget: IThemable, themeService: ITheme
inputValidationErrorBorder?: ColorIdentifier,
inputValidationErrorBackground?: ColorIdentifier
}): IDisposable {
return attachStyler(themeService, widget, {
return doAttachStyler(themeService, {
inputBackground: (style && style.inputBackground) || inputBackground,
inputForeground: (style && style.inputForeground) || inputForeground,
inputBorder: (style && style.inputBorder) || inputBorder,
@ -97,7 +103,7 @@ export function attachFindInputBoxStyler(widget: IThemable, themeService: ITheme
inputValidationWarningBackground: (style && style.inputValidationWarningBackground) || inputValidationWarningBackground,
inputValidationErrorBorder: (style && style.inputValidationErrorBorder) || inputValidationErrorBorder,
inputValidationErrorBackground: (style && style.inputValidationErrorBackground) || inputValidationErrorBackground
});
}, widget);
}
export function attachQuickOpenStyler(widget: IThemable, themeService: IThemeService, style?: {
@ -129,7 +135,7 @@ export function attachQuickOpenStyler(widget: IThemable, themeService: IThemeSer
listSelectionOutline?: ColorIdentifier,
listHoverOutline?: ColorIdentifier
}): IDisposable {
return attachStyler(themeService, widget, {
return doAttachStyler(themeService, {
foreground: (style && style.foreground) || foreground,
background: (style && style.background) || editorBackground,
borderColor: style && style.borderColor || contrastBorder,
@ -157,7 +163,7 @@ export function attachQuickOpenStyler(widget: IThemable, themeService: IThemeSer
listFocusOutline: (style && style.listFocusOutline) || activeContrastBorder,
listSelectionOutline: (style && style.listSelectionOutline) || activeContrastBorder,
listHoverOutline: (style && style.listHoverOutline) || activeContrastBorder
});
}, widget);
}
export function attachListStyler(widget: IThemable, themeService: IThemeService, style?: {
@ -176,7 +182,7 @@ export function attachListStyler(widget: IThemable, themeService: IThemeService,
listSelectionOutline?: ColorIdentifier,
listHoverOutline?: ColorIdentifier,
}): IDisposable {
return attachStyler(themeService, widget, {
return doAttachStyler(themeService, {
listFocusBackground: (style && style.listFocusBackground) || listFocusBackground,
listActiveSelectionBackground: (style && style.listActiveSelectionBackground) || lighten(listActiveSelectionBackground, 0.1),
listActiveSelectionForeground: (style && style.listActiveSelectionForeground) || listActiveSelectionForeground,
@ -191,20 +197,24 @@ export function attachListStyler(widget: IThemable, themeService: IThemeService,
listSelectionOutline: (style && style.listSelectionOutline) || activeContrastBorder,
listHoverOutline: (style && style.listHoverOutline) || activeContrastBorder,
listInactiveFocusOutline: style && style.listInactiveFocusOutline // not defined by default, only opt-in
});
}, widget);
}
export function attachHeaderViewStyler(widget: IThemable, themeService: IThemeService, options?: { noContrastBorder?: boolean }): IDisposable {
return attachStyler(themeService, widget, {
return doAttachStyler(themeService, {
headerBackground: SIDE_BAR_SECTION_HEADER_BACKGROUND,
headerHighContrastBorder: (options && options.noContrastBorder) ? null : contrastBorder
});
}, widget);
}
export function attachButtonStyler(widget: IThemable, themeService: IThemeService, style?: { buttonForeground?: ColorIdentifier, buttonBackground?: ColorIdentifier, buttonHoverBackground?: ColorIdentifier }): IDisposable {
return attachStyler(themeService, widget, {
return doAttachStyler(themeService, {
buttonForeground: (style && style.buttonForeground) || buttonForeground,
buttonBackground: (style && style.buttonBackground) || buttonBackground,
buttonHoverBackground: (style && style.buttonHoverBackground) || buttonHoverBackground
});
}, widget);
}
export function attachStylerCallback(themeService: IThemeService, colors: { [name: string]: ColorIdentifier }, callback: styleFn): IDisposable {
return doAttachStyler(themeService, colors, callback);
}

View file

@ -21,8 +21,9 @@ import { Dimension } from 'vs/base/browser/builder';
import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { ICodeEditor, IOverlayWidget, IOverlayWidgetPosition } from 'vs/editor/browser/editorBrowser';
import { attachInputBoxStyler } from 'vs/platform/theme/common/styler';
import { attachInputBoxStyler, attachStylerCallback } from 'vs/platform/theme/common/styler';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { editorWidgetBackground, widgetShadow } from "vs/platform/theme/common/colorRegistry";
class KeybindingInputWidget extends Widget {
@ -128,8 +129,11 @@ export class DefineKeybindingWidget extends Widget {
private _onHide = this._register(new Emitter<void>());
constructor(parent: HTMLElement, @IKeybindingService private keybindingService: IKeybindingService,
@IInstantiationService private instantiationService: IInstantiationService
constructor(
parent: HTMLElement,
@IKeybindingService private keybindingService: IKeybindingService,
@IInstantiationService private instantiationService: IInstantiationService,
@IThemeService private themeService: IThemeService
) {
super();
this.create();
@ -186,6 +190,16 @@ export class DefineKeybindingWidget extends Widget {
this._domNode.setHeight(DefineKeybindingWidget.HEIGHT);
dom.append(this._domNode.domNode, dom.$('.message', null, nls.localize('defineKeybinding.initial', "Press desired key combination and ENTER. ESCAPE to cancel.")));
this._register(attachStylerCallback(this.themeService, { editorWidgetBackground, widgetShadow }, colors => {
this._domNode.domNode.style.backgroundColor = colors.editorWidgetBackground;
if (colors.widgetShadow) {
this._domNode.domNode.style.boxShadow = `0 2px 8px ${colors.widgetShadow}`;
} else {
this._domNode.domNode.style.boxShadow = null;
}
}));
this._keybindingInputWidget = this._register(this.instantiationService.createInstance(KeybindingInputWidget, this._domNode.domNode, {}));
this._register(this._keybindingInputWidget.onKeybinding(keybinding => this.printKeybinding(keybinding)));
this._register(this._keybindingInputWidget.onEnter(() => this.hide()));

View file

@ -34,18 +34,6 @@
margin: 0px 4px;
}
/* Theming */
.defineKeybindingWidget {
background-color: #EFEFF2;
box-shadow: 0 2px 8px #A8A8A8;
}
.hc-black .defineKeybindingWidget,
.vs-dark .defineKeybindingWidget {
background-color: #2D2D30;
box-shadow: 0 2px 8px #000;
}
/* Editor decorations */
.monaco-editor .inlineKeybindingInfo:before {
margin: 0.2em 0.1em 0 0.1em;

View file

@ -238,8 +238,6 @@
}
.monaco-editor .floating-click-widget {
background: #007ACC;
color: white;
padding: 10px;
border-radius: 5px;
cursor: pointer;

View file

@ -23,10 +23,11 @@ import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace
import { ConfigurationTarget } from 'vs/workbench/services/configuration/common/configurationEditing';
import { ActionsOrientation, ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
import { Action } from 'vs/base/common/actions';
import { attachInputBoxStyler } from 'vs/platform/theme/common/styler';
import { attachInputBoxStyler, attachStylerCallback } from 'vs/platform/theme/common/styler';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { Position } from 'vs/editor/common/core/position';
import { ICursorPositionChangedEvent } from 'vs/editor/common/controller/cursorEvents';
import { buttonBackground, buttonForeground } from "vs/platform/theme/common/colorRegistry";
export class SettingsGroupTitleWidget extends Widget implements IViewZone {
@ -360,10 +361,15 @@ export class FloatingClickWidget extends Widget implements IOverlayWidget {
private _onClick: Emitter<void> = this._register(new Emitter<void>());
public onClick: Event<void> = this._onClick.event;
constructor(private editor: ICodeEditor, private label: string, private keyBindingAction: string,
@IKeybindingService keybindingService: IKeybindingService
constructor(
private editor: ICodeEditor,
private label: string,
private keyBindingAction: string,
@IKeybindingService keybindingService: IKeybindingService,
@IThemeService private themeService: IThemeService
) {
super();
if (keyBindingAction) {
let keybinding = keybindingService.lookupKeybinding(keyBindingAction);
if (keybinding) {
@ -374,6 +380,11 @@ export class FloatingClickWidget extends Widget implements IOverlayWidget {
public render() {
this._domNode = DOM.$('.floating-click-widget');
this._register(attachStylerCallback(this.themeService, { buttonBackground, buttonForeground }, colors => {
this._domNode.style.backgroundColor = colors.buttonBackground;
this._domNode.style.color = colors.buttonForeground;
}));
DOM.append(this._domNode, DOM.$('')).textContent = this.label;
this.onclick(this._domNode, e => this._onClick.fire());
this.editor.addOverlayWidget(this);