提交 6ad67e2a 编写于 作者: B Benjamin Pasero

ui debt - align status bar flyovers closer to each other

上级 43ead816
...@@ -12,7 +12,7 @@ import { Gesture, EventType as GestureEventType } from 'vs/base/browser/touch'; ...@@ -12,7 +12,7 @@ import { Gesture, EventType as GestureEventType } from 'vs/base/browser/touch';
import { ActionRunner, IAction, IActionRunner } from 'vs/base/common/actions'; import { ActionRunner, IAction, IActionRunner } from 'vs/base/common/actions';
import { BaseActionItem, IActionItemProvider } from 'vs/base/browser/ui/actionbar/actionbar'; import { BaseActionItem, IActionItemProvider } from 'vs/base/browser/ui/actionbar/actionbar';
import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { IContextViewProvider } from 'vs/base/browser/ui/contextview/contextview'; import { IContextViewProvider, IAnchor } from 'vs/base/browser/ui/contextview/contextview';
import { IMenuOptions } from 'vs/base/browser/ui/menu/menu'; import { IMenuOptions } from 'vs/base/browser/ui/menu/menu';
import { ResolvedKeybinding } from 'vs/base/common/keyCodes'; import { ResolvedKeybinding } from 'vs/base/common/keyCodes';
import { EventHelper, EventType } from 'vs/base/browser/dom'; import { EventHelper, EventType } from 'vs/base/browser/dom';
...@@ -33,6 +33,7 @@ export class BaseDropdown extends ActionRunner { ...@@ -33,6 +33,7 @@ export class BaseDropdown extends ActionRunner {
private $boxContainer: Builder; private $boxContainer: Builder;
private $label: Builder; private $label: Builder;
private $contents: Builder; private $contents: Builder;
private visible: boolean;
constructor(container: HTMLElement, options: IBaseDropdownOptions) { constructor(container: HTMLElement, options: IBaseDropdownOptions) {
super(); super();
...@@ -58,7 +59,11 @@ export class BaseDropdown extends ActionRunner { ...@@ -58,7 +59,11 @@ export class BaseDropdown extends ActionRunner {
return; // prevent multiple clicks to open multiple context menus (https://github.com/Microsoft/vscode/issues/41363) return; // prevent multiple clicks to open multiple context menus (https://github.com/Microsoft/vscode/issues/41363)
} }
this.show(); if (this.visible) {
this.hide();
} else {
this.show();
}
}).appendTo(this.$el); }).appendTo(this.$el);
let cleanupFn = labelRenderer(this.$label.getHTMLElement()); let cleanupFn = labelRenderer(this.$label.getHTMLElement());
...@@ -87,11 +92,11 @@ export class BaseDropdown extends ActionRunner { ...@@ -87,11 +92,11 @@ export class BaseDropdown extends ActionRunner {
} }
public show(): void { public show(): void {
// noop this.visible = true;
} }
public hide(): void { public hide(): void {
// noop this.visible = false;
} }
protected onEvent(e: Event, activeElement: HTMLElement): void { protected onEvent(e: Event, activeElement: HTMLElement): void {
...@@ -135,10 +140,12 @@ export class Dropdown extends BaseDropdown { ...@@ -135,10 +140,12 @@ export class Dropdown extends BaseDropdown {
} }
public show(): void { public show(): void {
super.show();
this.element.addClass('active'); this.element.addClass('active');
this.contextViewProvider.showContextView({ this.contextViewProvider.showContextView({
getAnchor: () => this.element.getHTMLElement(), getAnchor: () => this.getAnchor(),
render: (container) => { render: (container) => {
return this.renderContents(container); return this.renderContents(container);
...@@ -148,13 +155,21 @@ export class Dropdown extends BaseDropdown { ...@@ -148,13 +155,21 @@ export class Dropdown extends BaseDropdown {
this.onEvent(e, activeElement); this.onEvent(e, activeElement);
}, },
onHide: () => { onHide: () => this.onHide()
this.element.removeClass('active');
}
}); });
} }
protected getAnchor(): HTMLElement | IAnchor {
return this.element.getHTMLElement();
}
protected onHide(): void {
this.element.removeClass('active');
}
public hide(): void { public hide(): void {
super.hide();
if (this.contextViewProvider) { if (this.contextViewProvider) {
this.contextViewProvider.hideContextView(); this.contextViewProvider.hideContextView();
} }
...@@ -217,6 +232,8 @@ export class DropdownMenu extends BaseDropdown { ...@@ -217,6 +232,8 @@ export class DropdownMenu extends BaseDropdown {
} }
public show(): void { public show(): void {
super.show();
this.element.addClass('active'); this.element.addClass('active');
this._contextMenuProvider.showContextMenu({ this._contextMenuProvider.showContextMenu({
...@@ -232,7 +249,7 @@ export class DropdownMenu extends BaseDropdown { ...@@ -232,7 +249,7 @@ export class DropdownMenu extends BaseDropdown {
} }
public hide(): void { public hide(): void {
// noop super.hide();
} }
} }
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
import 'vs/css!./media/editorstatus'; import 'vs/css!./media/editorstatus';
import nls = require('vs/nls'); import nls = require('vs/nls');
import { TPromise } from 'vs/base/common/winjs.base'; import { TPromise } from 'vs/base/common/winjs.base';
import { $, append, runAtThisOrScheduleAtNextAnimationFrame, addDisposableListener } from 'vs/base/browser/dom'; import { $, append, runAtThisOrScheduleAtNextAnimationFrame, addDisposableListener, getDomNodePagePosition } from 'vs/base/browser/dom';
import strings = require('vs/base/common/strings'); import strings = require('vs/base/common/strings');
import paths = require('vs/base/common/paths'); import paths = require('vs/base/common/paths');
import types = require('vs/base/common/types'); import types = require('vs/base/common/types');
...@@ -50,13 +50,15 @@ import { IConfigurationChangedEvent, IEditorOptions } from 'vs/editor/common/con ...@@ -50,13 +50,15 @@ import { IConfigurationChangedEvent, IEditorOptions } from 'vs/editor/common/con
import { ITextResourceConfigurationService } from 'vs/editor/common/services/resourceConfiguration'; import { ITextResourceConfigurationService } from 'vs/editor/common/services/resourceConfiguration';
import { IThemeService } from 'vs/platform/theme/common/themeService'; import { IThemeService } from 'vs/platform/theme/common/themeService';
import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
import { attachStylerCallback, attachButtonStyler } from 'vs/platform/theme/common/styler'; import { attachButtonStyler } from 'vs/platform/theme/common/styler';
import { widgetShadow, editorWidgetBackground } from 'vs/platform/theme/common/colorRegistry'; import { widgetShadow, editorWidgetBackground, foreground, darken, contrastBorder } from 'vs/platform/theme/common/colorRegistry';
import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration';
import { deepClone } from 'vs/base/common/objects'; import { deepClone } from 'vs/base/common/objects';
import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
import { Button } from 'vs/base/browser/ui/button/button'; import { Button } from 'vs/base/browser/ui/button/button';
import { Schemas } from 'vs/base/common/network'; import { Schemas } from 'vs/base/common/network';
import { IAnchor } from 'vs/base/browser/ui/contextview/contextview';
import { Themable } from 'vs/workbench/common/theme';
// TODO@Sandeep layer breaker // TODO@Sandeep layer breaker
// tslint:disable-next-line:import-patterns // tslint:disable-next-line:import-patterns
...@@ -271,7 +273,7 @@ export class EditorStatus implements IStatusbarItem { ...@@ -271,7 +273,7 @@ export class EditorStatus implements IStatusbarItem {
private activeEditorListeners: IDisposable[]; private activeEditorListeners: IDisposable[];
private delayedRender: IDisposable; private delayedRender: IDisposable;
private toRender: StateChange; private toRender: StateChange;
private lastScreenReaderExplanation: ScreenReaderDetectedExplanation; private screenReaderExplanation: ScreenReaderDetectedExplanation;
constructor( constructor(
@IWorkbenchEditorService private editorService: IWorkbenchEditorService, @IWorkbenchEditorService private editorService: IWorkbenchEditorService,
...@@ -286,7 +288,6 @@ export class EditorStatus implements IStatusbarItem { ...@@ -286,7 +288,6 @@ export class EditorStatus implements IStatusbarItem {
this.toDispose = []; this.toDispose = [];
this.activeEditorListeners = []; this.activeEditorListeners = [];
this.state = new State(); this.state = new State();
this.lastScreenReaderExplanation = null;
} }
public render(container: HTMLElement): IDisposable { public render(container: HTMLElement): IDisposable {
...@@ -484,7 +485,18 @@ export class EditorStatus implements IStatusbarItem { ...@@ -484,7 +485,18 @@ export class EditorStatus implements IStatusbarItem {
} }
private onScreenReaderModeClick(): void { private onScreenReaderModeClick(): void {
this.lastScreenReaderExplanation = this.instantiationService.createInstance(ScreenReaderDetectedExplanation, this.screenRedearModeElement); const showExplanation = !this.screenReaderExplanation || !this.screenReaderExplanation.visible;
if (!this.screenReaderExplanation) {
this.screenReaderExplanation = this.instantiationService.createInstance(ScreenReaderDetectedExplanation);
this.toDispose.push(this.screenReaderExplanation);
}
if (showExplanation) {
this.screenReaderExplanation.show(this.screenRedearModeElement);
} else {
this.screenReaderExplanation.hide();
}
} }
private onSelectionClick(): void { private onSelectionClick(): void {
...@@ -649,9 +661,8 @@ export class EditorStatus implements IStatusbarItem { ...@@ -649,9 +661,8 @@ export class EditorStatus implements IStatusbarItem {
screenReaderMode = (editorWidget.getConfiguration().accessibilitySupport === AccessibilitySupport.Enabled); screenReaderMode = (editorWidget.getConfiguration().accessibilitySupport === AccessibilitySupport.Enabled);
} }
if (screenReaderMode === false && this.lastScreenReaderExplanation) { if (screenReaderMode === false && this.screenReaderExplanation && this.screenReaderExplanation.visible) {
this.lastScreenReaderExplanation.hide(); this.screenReaderExplanation.hide();
this.lastScreenReaderExplanation = null;
} }
this.updateState({ screenReaderMode: screenReaderMode }); this.updateState({ screenReaderMode: screenReaderMode });
...@@ -1218,111 +1229,146 @@ export class ChangeEncodingAction extends Action { ...@@ -1218,111 +1229,146 @@ export class ChangeEncodingAction extends Action {
} }
} }
class ScreenReaderDetectedExplanation { class ScreenReaderDetectedExplanation extends Themable {
private container: HTMLElement;
private _isDisposed: boolean; private hrElement: HTMLHRElement;
private _toDispose: IDisposable[]; private _visible: boolean;
constructor( constructor(
anchorElement: HTMLElement, @IThemeService themeService: IThemeService,
@IThemeService private readonly themeService: IThemeService,
@IContextViewService private readonly contextViewService: IContextViewService, @IContextViewService private readonly contextViewService: IContextViewService,
@IWorkspaceConfigurationService private readonly configurationService: IWorkspaceConfigurationService, @IWorkspaceConfigurationService private readonly configurationService: IWorkspaceConfigurationService,
) { ) {
this._isDisposed = false; super(themeService);
this._toDispose = []; }
this.contextViewService.showContextView({ public get visible(): boolean {
getAnchor: () => anchorElement, return this._visible;
}
protected updateStyles(): void {
if (this.container) {
const background = this.getColor(editorWidgetBackground);
this.container.style.backgroundColor = background ? background.toString() : null;
const widgetShadowColor = this.getColor(widgetShadow);
this.container.style.boxShadow = widgetShadowColor ? `0 0px 8px ${widgetShadowColor}` : null;
const contrastBorderColor = this.getColor(contrastBorder);
this.container.style.border = contrastBorderColor ? `1px solid ${contrastBorderColor}` : null;
const foregroundColor = this.getColor(foreground);
this.hrElement.style.backgroundColor = foregroundColor ? foregroundColor.toString() : null;
}
}
public show(anchorElement: HTMLElement): void {
this._visible = true;
this.contextViewService.showContextView({
getAnchor: () => {
const res = getDomNodePagePosition(anchorElement);
return {
x: res.left,
y: res.top - 9, /* above the status bar */
width: res.width,
height: res.height
} as IAnchor;
},
render: (container) => { render: (container) => {
return this.renderContents(container); return this.renderContents(container);
}, },
onDOMEvent: (e, activeElement) => { },
onDOMEvent: (e, activeElement) => {
},
onHide: () => { onHide: () => {
this.dispose(); this._visible = false;
} }
}); });
} }
public dispose(): void {
this._isDisposed = true;
this._toDispose = dispose(this._toDispose);
}
public hide(): void { public hide(): void {
if (this._isDisposed) {
return;
}
this.contextViewService.hideContextView(); this.contextViewService.hideContextView();
} }
protected renderContents(container: HTMLElement): IDisposable { protected renderContents(parent: HTMLElement): IDisposable {
const domNode = $('div.screen-reader-detected-explanation', { const toDispose: IDisposable[] = [];
this.container = $('div.screen-reader-detected-explanation', {
'aria-hidden': 'true' 'aria-hidden': 'true'
}); });
const title = $('h2.title', {}, nls.localize('screenReaderDetectedExplanation.title', "Screen Reader Optimized")); const title = $('h2.title', {}, nls.localize('screenReaderDetectedExplanation.title', "Screen Reader Optimized"));
domNode.appendChild(title); this.container.appendChild(title);
const closeBtn = $('div.cancel'); const closeBtn = $('div.cancel');
this._toDispose.push(addDisposableListener(closeBtn, 'click', () => { toDispose.push(addDisposableListener(closeBtn, 'click', () => {
this.contextViewService.hideContextView(); this.contextViewService.hideContextView();
})); }));
domNode.appendChild(closeBtn); toDispose.push(addDisposableListener(closeBtn, 'mouseover', () => {
const theme = this.themeService.getTheme();
let darkenFactor: number;
switch (theme.type) {
case 'light':
darkenFactor = 0.1;
break;
case 'dark':
darkenFactor = 0.2;
break;
}
if (darkenFactor) {
closeBtn.style.backgroundColor = this.getColor(editorWidgetBackground, (color, theme) => darken(color, darkenFactor)(theme));
}
}));
toDispose.push(addDisposableListener(closeBtn, 'mouseout', () => {
closeBtn.style.backgroundColor = null;
}));
this.container.appendChild(closeBtn);
const question = $('p.question', {}, nls.localize('screenReaderDetectedExplanation.question', "Are you using a screen reader to operate VS Code?")); const question = $('p.question', {}, nls.localize('screenReaderDetectedExplanation.question', "Are you using a screen reader to operate VS Code?"));
domNode.appendChild(question); this.container.appendChild(question);
const buttonContainer = $('div.buttons'); const buttonContainer = $('div.buttons');
domNode.appendChild(buttonContainer); this.container.appendChild(buttonContainer);
const yesBtn = new Button(buttonContainer); const yesBtn = new Button(buttonContainer);
yesBtn.label = nls.localize('screenReaderDetectedExplanation.answerYes', "Yes"); yesBtn.label = nls.localize('screenReaderDetectedExplanation.answerYes', "Yes");
this._toDispose.push(attachButtonStyler(yesBtn, this.themeService)); toDispose.push(attachButtonStyler(yesBtn, this.themeService));
this._toDispose.push(yesBtn.onDidClick(e => { toDispose.push(yesBtn.onDidClick(e => {
this.configurationService.updateValue('editor.accessibilitySupport', 'on', ConfigurationTarget.USER); this.configurationService.updateValue('editor.accessibilitySupport', 'on', ConfigurationTarget.USER);
this.contextViewService.hideContextView(); this.contextViewService.hideContextView();
})); }));
const noBtn = new Button(buttonContainer); const noBtn = new Button(buttonContainer);
noBtn.label = nls.localize('screenReaderDetectedExplanation.answerNo', "No"); noBtn.label = nls.localize('screenReaderDetectedExplanation.answerNo', "No");
this._toDispose.push(attachButtonStyler(noBtn, this.themeService)); toDispose.push(attachButtonStyler(noBtn, this.themeService));
this._toDispose.push(noBtn.onDidClick(e => { toDispose.push(noBtn.onDidClick(e => {
this.configurationService.updateValue('editor.accessibilitySupport', 'off', ConfigurationTarget.USER); this.configurationService.updateValue('editor.accessibilitySupport', 'off', ConfigurationTarget.USER);
this.contextViewService.hideContextView(); this.contextViewService.hideContextView();
})); }));
const clear = $('div'); const clear = $('div');
clear.style.clear = 'both'; clear.style.clear = 'both';
domNode.appendChild(clear); this.container.appendChild(clear);
const br = $('br'); const br = $('br');
domNode.appendChild(br); this.container.appendChild(br);
const hr = $('hr'); this.hrElement = $('hr');
domNode.appendChild(hr); this.container.appendChild(this.hrElement);
const explanation1 = $('p.body1', {}, nls.localize('screenReaderDetectedExplanation.body1', "VS Code is now optimized for usage with a screen reader.")); const explanation1 = $('p.body1', {}, nls.localize('screenReaderDetectedExplanation.body1', "VS Code is now optimized for usage with a screen reader."));
domNode.appendChild(explanation1); this.container.appendChild(explanation1);
const explanation2 = $('p.body2', {}, nls.localize('screenReaderDetectedExplanation.body2', "Some editor features will have different behaviour: e.g. word wrapping, folding, etc.")); const explanation2 = $('p.body2', {}, nls.localize('screenReaderDetectedExplanation.body2', "Some editor features will have different behaviour: e.g. word wrapping, folding, etc."));
domNode.appendChild(explanation2); this.container.appendChild(explanation2);
container.appendChild(domNode); parent.appendChild(this.container);
this._toDispose.push(attachStylerCallback(this.themeService, { widgetShadow, editorWidgetBackground }, colors => { this.updateStyles();
domNode.style.backgroundColor = colors.editorWidgetBackground;
if (colors.widgetShadow) {
domNode.style.boxShadow = `0 5px 8px ${colors.widgetShadow}`;
}
}));
return { return {
dispose: () => { this.dispose(); } dispose: () => dispose(toDispose)
}; };
} }
} }
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
cursor: default !important; cursor: default !important;
} }
.monaco-shell .screen-reader-detected-explanation { .monaco-shell .screen-reader-detected-explanation {
width: 420px; width: 420px;
top: 30px; top: 30px;
...@@ -53,8 +52,9 @@ ...@@ -53,8 +52,9 @@
font-size: 1.2em; font-size: 1.2em;
} }
.monaco-shell .screen-reader-detected-explanation p.question { .monaco-shell .screen-reader-detected-explanation hr {
font-size: 1.4em; border: 0;
height: 2px;
} }
.monaco-shell .screen-reader-detected-explanation .buttons { .monaco-shell .screen-reader-detected-explanation .buttons {
...@@ -72,21 +72,8 @@ ...@@ -72,21 +72,8 @@
.monaco-shell.vs .screen-reader-detected-explanation .cancel { .monaco-shell.vs .screen-reader-detected-explanation .cancel {
background: url('close-big.svg') center center no-repeat; background: url('close-big.svg') center center no-repeat;
} }
.monaco-shell.vs .screen-reader-detected-explanation .cancel:hover {
background-color: #eaeaea;
}
.monaco-shell.vs-dark .screen-reader-detected-explanation .cancel, .monaco-shell.vs-dark .screen-reader-detected-explanation .cancel,
.monaco-shell.hc-black .screen-reader-detected-explanation .cancel { .monaco-shell.hc-black .screen-reader-detected-explanation .cancel {
background: url('close-big-dark.svg') center center no-repeat; background: url('close-big-dark.svg') center center no-repeat;
} }
.monaco-shell.vs-dark .screen-reader-detected-explanation .cancel:hover { \ No newline at end of file
background-color: rgba(30,30,30,0.8);
}
.monaco-shell.hc-black .screen-reader-detected-explanation .cancel {
opacity: 0.6;
}
.monaco-shell.hc-black .screen-reader-detected-explanation .cancel:hover {
opacity: 1;
}
...@@ -1277,7 +1277,6 @@ export class Workbench implements IPartService { ...@@ -1277,7 +1277,6 @@ export class Workbench implements IPartService {
// Notifications Status // Notifications Status
const notificationsStatus = this.instantiationService.createInstance(NotificationsStatus, this.notificationService.model); const notificationsStatus = this.instantiationService.createInstance(NotificationsStatus, this.notificationService.model);
this.toUnbind.push(notificationsStatus);
// Eventing // Eventing
this.toUnbind.push(this.notificationsCenter.onDidChangeVisibility(() => { this.toUnbind.push(this.notificationsCenter.onDidChangeVisibility(() => {
......
...@@ -18,9 +18,10 @@ import * as errors from 'vs/base/common/errors'; ...@@ -18,9 +18,10 @@ import * as errors from 'vs/base/common/errors';
import { IIntegrityService } from 'vs/platform/integrity/common/integrity'; import { IIntegrityService } from 'vs/platform/integrity/common/integrity';
import { IThemeService, registerThemingParticipant, ITheme, ICssStyleCollector } from 'vs/platform/theme/common/themeService'; import { IThemeService, registerThemingParticipant, ITheme, ICssStyleCollector } from 'vs/platform/theme/common/themeService';
import { attachStylerCallback } from 'vs/platform/theme/common/styler'; import { attachStylerCallback } from 'vs/platform/theme/common/styler';
import { editorWidgetBackground, widgetShadow, inputBorder, inputForeground, inputBackground, inputActiveOptionBorder, editorBackground, buttonBackground, contrastBorder } from 'vs/platform/theme/common/colorRegistry'; import { editorWidgetBackground, widgetShadow, inputBorder, inputForeground, inputBackground, inputActiveOptionBorder, editorBackground, buttonBackground, contrastBorder, darken } from 'vs/platform/theme/common/colorRegistry';
import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration';
import { ITelemetryService } from '../../../../platform/telemetry/common/telemetry'; import { ITelemetryService } from '../../../../platform/telemetry/common/telemetry';
import { IAnchor } from 'vs/base/browser/ui/contextview/contextview';
export const FEEDBACK_VISIBLE_CONFIG = 'workbench.statusBar.feedback.visible'; export const FEEDBACK_VISIBLE_CONFIG = 'workbench.statusBar.feedback.visible';
...@@ -37,6 +38,7 @@ export interface IFeedbackService { ...@@ -37,6 +38,7 @@ export interface IFeedbackService {
export interface IFeedbackDropdownOptions { export interface IFeedbackDropdownOptions {
contextViewProvider: IContextViewService; contextViewProvider: IContextViewService;
feedbackService?: IFeedbackService; feedbackService?: IFeedbackService;
onFeedbackVisibilityChange?: (visible: boolean) => void;
} }
enum FormEvent { enum FormEvent {
...@@ -69,7 +71,7 @@ export class FeedbackDropdown extends Dropdown { ...@@ -69,7 +71,7 @@ export class FeedbackDropdown extends Dropdown {
constructor( constructor(
container: HTMLElement, container: HTMLElement,
options: IFeedbackDropdownOptions, private options: IFeedbackDropdownOptions,
@ICommandService private commandService: ICommandService, @ICommandService private commandService: ICommandService,
@ITelemetryService private telemetryService: ITelemetryService, @ITelemetryService private telemetryService: ITelemetryService,
@IIntegrityService private integrityService: IIntegrityService, @IIntegrityService private integrityService: IIntegrityService,
...@@ -112,6 +114,17 @@ export class FeedbackDropdown extends Dropdown { ...@@ -112,6 +114,17 @@ export class FeedbackDropdown extends Dropdown {
this.requestFeatureLink = product.sendASmile.requestFeatureUrl; this.requestFeatureLink = product.sendASmile.requestFeatureUrl;
} }
protected getAnchor(): HTMLElement | IAnchor {
const res = dom.getDomNodePagePosition(this.element.getHTMLElement());
return {
x: res.left,
y: res.top - 9, /* above the status bar */
width: res.width,
height: res.height
} as IAnchor;
}
protected renderContents(container: HTMLElement): IDisposable { protected renderContents(container: HTMLElement): IDisposable {
const $form = $('form.feedback-form').attr({ const $form = $('form.feedback-form').attr({
action: 'javascript:void(0);' action: 'javascript:void(0);'
...@@ -123,7 +136,27 @@ export class FeedbackDropdown extends Dropdown { ...@@ -123,7 +136,27 @@ export class FeedbackDropdown extends Dropdown {
$('h2.title').text(nls.localize("label.sendASmile", "Tweet us your feedback.")).appendTo($form); $('h2.title').text(nls.localize("label.sendASmile", "Tweet us your feedback.")).appendTo($form);
this.invoke($('div.cancel').attr('tabindex', '0'), () => { const cancelBtn = $('div.cancel').attr('tabindex', '0');
cancelBtn.on(dom.EventType.MOUSE_OVER, () => {
const theme = this.themeService.getTheme();
let darkenFactor: number;
switch (theme.type) {
case 'light':
darkenFactor = 0.1;
break;
case 'dark':
darkenFactor = 0.2;
break;
}
if (darkenFactor) {
cancelBtn.getHTMLElement().style.backgroundColor = darken(theme.getColor(editorWidgetBackground), darkenFactor)(theme).toString();
}
});
cancelBtn.on(dom.EventType.MOUSE_OUT, () => {
cancelBtn.getHTMLElement().style.backgroundColor = null;
});
this.invoke(cancelBtn, () => {
this.hide(); this.hide();
}).appendTo($form); }).appendTo($form);
...@@ -223,7 +256,7 @@ export class FeedbackDropdown extends Dropdown { ...@@ -223,7 +256,7 @@ export class FeedbackDropdown extends Dropdown {
this.toDispose.push(attachStylerCallback(this.themeService, { widgetShadow, editorWidgetBackground, inputBackground, inputForeground, inputBorder, editorBackground, contrastBorder }, colors => { this.toDispose.push(attachStylerCallback(this.themeService, { widgetShadow, editorWidgetBackground, inputBackground, inputForeground, inputBorder, editorBackground, contrastBorder }, colors => {
$form.style('background-color', colors.editorWidgetBackground); $form.style('background-color', colors.editorWidgetBackground);
$form.style('box-shadow', colors.widgetShadow ? `0 5px 8px ${colors.widgetShadow}` : null); $form.style('box-shadow', colors.widgetShadow ? `0 0 8px ${colors.widgetShadow}` : null);
if (this.feedbackDescriptionInput) { if (this.feedbackDescriptionInput) {
this.feedbackDescriptionInput.style.backgroundColor = colors.inputBackground; this.feedbackDescriptionInput.style.backgroundColor = colors.inputBackground;
...@@ -293,6 +326,20 @@ export class FeedbackDropdown extends Dropdown { ...@@ -293,6 +326,20 @@ export class FeedbackDropdown extends Dropdown {
return element; return element;
} }
public show(): void {
super.show();
if (this.options.onFeedbackVisibilityChange) {
this.options.onFeedbackVisibilityChange(true);
}
}
protected onHide(): void {
if (this.options.onFeedbackVisibilityChange) {
this.options.onFeedbackVisibilityChange(false);
}
}
public hide(): void { public hide(): void {
if (this.feedbackDescriptionInput) { if (this.feedbackDescriptionInput) {
this.feedback = this.feedbackDescriptionInput.value; this.feedback = this.feedbackDescriptionInput.value;
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { IStatusbarItem } from 'vs/workbench/browser/parts/statusbar/statusbar'; import { IStatusbarItem } from 'vs/workbench/browser/parts/statusbar/statusbar';
import { FeedbackDropdown, IFeedback, IFeedbackService, FEEDBACK_VISIBLE_CONFIG } from 'vs/workbench/parts/feedback/electron-browser/feedback'; import { FeedbackDropdown, IFeedback, IFeedbackService, FEEDBACK_VISIBLE_CONFIG, IFeedbackDropdownOptions } from 'vs/workbench/parts/feedback/electron-browser/feedback';
import { IContextViewService, IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { IContextViewService, IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import product from 'vs/platform/node/product'; import product from 'vs/platform/node/product';
...@@ -16,7 +16,7 @@ import { IThemeService, registerThemingParticipant, ITheme, ICssStyleCollector } ...@@ -16,7 +16,7 @@ import { IThemeService, registerThemingParticipant, ITheme, ICssStyleCollector }
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration';
import { IConfigurationChangeEvent } from 'vs/platform/configuration/common/configuration'; import { IConfigurationChangeEvent } from 'vs/platform/configuration/common/configuration';
import { clearNode, EventHelper } from 'vs/base/browser/dom'; import { clearNode, EventHelper, addClass, removeClass } from 'vs/base/browser/dom';
import { $ } from 'vs/base/browser/builder'; import { $ } from 'vs/base/browser/builder';
import { localize } from 'vs/nls'; import { localize } from 'vs/nls';
import { TPromise } from 'vs/base/common/winjs.base'; import { TPromise } from 'vs/base/common/winjs.base';
...@@ -130,8 +130,15 @@ export class FeedbackStatusbarItem extends Themable implements IStatusbarItem { ...@@ -130,8 +130,15 @@ export class FeedbackStatusbarItem extends Themable implements IStatusbarItem {
if (!this.dropdown) { if (!this.dropdown) {
this.dropdown = this.instantiationService.createInstance(FeedbackDropdown, this.container, { this.dropdown = this.instantiationService.createInstance(FeedbackDropdown, this.container, {
contextViewProvider: this.contextViewService, contextViewProvider: this.contextViewService,
feedbackService: this.instantiationService.createInstance(TwitterFeedbackService) feedbackService: this.instantiationService.createInstance(TwitterFeedbackService),
}); onFeedbackVisibilityChange: visible => {
if (visible) {
addClass(this.container, 'has-beak');
} else {
removeClass(this.container, 'has-beak');
}
}
} as IFeedbackDropdownOptions);
this.toUnbind.push(this.dropdown); this.toUnbind.push(this.dropdown);
this.updateStyles(); this.updateStyles();
......
...@@ -151,10 +151,6 @@ ...@@ -151,10 +151,6 @@
background: url('close.svg') center center no-repeat; background: url('close.svg') center center no-repeat;
} }
.monaco-shell.vs .feedback-form .cancel:hover {
background-color: #eaeaea;
}
.monaco-shell .feedback-form .form-buttons { .monaco-shell .feedback-form .form-buttons {
display: flex; display: flex;
} }
...@@ -221,10 +217,6 @@ ...@@ -221,10 +217,6 @@
background: url('close-dark.svg') center center no-repeat; background: url('close-dark.svg') center center no-repeat;
} }
.monaco-shell.vs-dark .feedback-form .cancel:hover {
background-color: rgba(30,30,30,0.8);
}
.monaco-shell .feedback-form .sentiment.smile { .monaco-shell .feedback-form .sentiment.smile {
background-image: url('happy.svg'); background-image: url('happy.svg');
background-position: center; background-position: center;
...@@ -264,13 +256,6 @@ ...@@ -264,13 +256,6 @@
padding: 10px; padding: 10px;
float: right; float: right;
} }
.monaco-shell.hc-black .feedback-form .cancel {
opacity: 0.6;
}
.monaco-shell.hc-black .feedback-form .cancel:hover {
opacity: 1;
}
.monaco-shell.hc-black .feedback-form .form-buttons .send, .monaco-shell.hc-black .feedback-form .form-buttons .send,
.monaco-shell.hc-black .feedback-form .form-buttons .send.in-progress, .monaco-shell.hc-black .feedback-form .form-buttons .send.in-progress,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册