From 408ede050d518ccf2d2755ca604e000d4164c9d0 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 8 May 2017 19:44:35 +0200 Subject: [PATCH] theming - keybindings button and widget --- src/vs/platform/theme/common/styler.ts | 48 +++++++++++-------- .../preferences/browser/keybindingWidgets.ts | 20 ++++++-- .../preferences/browser/media/keybindings.css | 12 ----- .../preferences/browser/media/preferences.css | 2 - .../preferences/browser/preferencesWidgets.ts | 17 +++++-- 5 files changed, 60 insertions(+), 39 deletions(-) diff --git a/src/vs/platform/theme/common/styler.ts b/src/vs/platform/theme/common/styler.ts index 46b5f1bd0fa..ca14730cfd0 100644 --- a/src/vs/platform/theme/common/styler.ts +++ b/src/vs/platform/theme/common/styler.ts @@ -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); } \ No newline at end of file diff --git a/src/vs/workbench/parts/preferences/browser/keybindingWidgets.ts b/src/vs/workbench/parts/preferences/browser/keybindingWidgets.ts index ff98e9f5bc5..11a3ea7753a 100644 --- a/src/vs/workbench/parts/preferences/browser/keybindingWidgets.ts +++ b/src/vs/workbench/parts/preferences/browser/keybindingWidgets.ts @@ -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()); - 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())); diff --git a/src/vs/workbench/parts/preferences/browser/media/keybindings.css b/src/vs/workbench/parts/preferences/browser/media/keybindings.css index d7dbc15225f..f8f89e185e6 100644 --- a/src/vs/workbench/parts/preferences/browser/media/keybindings.css +++ b/src/vs/workbench/parts/preferences/browser/media/keybindings.css @@ -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; diff --git a/src/vs/workbench/parts/preferences/browser/media/preferences.css b/src/vs/workbench/parts/preferences/browser/media/preferences.css index 1bc95c360d3..d0f783fbcaa 100644 --- a/src/vs/workbench/parts/preferences/browser/media/preferences.css +++ b/src/vs/workbench/parts/preferences/browser/media/preferences.css @@ -238,8 +238,6 @@ } .monaco-editor .floating-click-widget { - background: #007ACC; - color: white; padding: 10px; border-radius: 5px; cursor: pointer; diff --git a/src/vs/workbench/parts/preferences/browser/preferencesWidgets.ts b/src/vs/workbench/parts/preferences/browser/preferencesWidgets.ts index 26e55c992fa..5d7cfc19695 100644 --- a/src/vs/workbench/parts/preferences/browser/preferencesWidgets.ts +++ b/src/vs/workbench/parts/preferences/browser/preferencesWidgets.ts @@ -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 = this._register(new Emitter()); public onClick: Event = 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);