未验证 提交 a42d26dc 编写于 作者: J Joao Moreno

Merge branch 'joao/empty-views'

/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
export interface ILink {
readonly label: string;
readonly href: string;
readonly title?: string;
}
export type LinkedTextNode = string | ILink;
export type LinkedText = LinkedTextNode[];
const LINK_REGEX = /\[([^\]]+)\]\(((?:https?:\/\/|command:)[^\)\s]+)(?: "([^"]+)")?\)/gi;
export function parseLinkedText(text: string): LinkedText {
const result: LinkedTextNode[] = [];
let index = 0;
let match: RegExpExecArray | null;
while (match = LINK_REGEX.exec(text)) {
if (match.index - index > 0) {
result.push(text.substring(index, match.index));
}
const [, label, href, title] = match;
if (title) {
result.push({ label, href, title });
} else {
result.push({ label, href });
}
index = match.index + match[0].length;
}
if (index < text.length) {
result.push(text.substring(index));
}
return result;
}
......@@ -14,7 +14,7 @@ import { Disposable } from 'vs/base/common/lifecycle';
import { Gesture, EventType } from 'vs/base/browser/touch';
export interface IButtonOptions extends IButtonStyles {
title?: boolean;
title?: boolean | string;
}
export interface IButtonStyles {
......@@ -150,7 +150,9 @@ export class Button extends Disposable {
DOM.addClass(this._element, 'monaco-text-button');
}
this._element.textContent = value;
if (this.options.title) {
if (typeof this.options.title === 'string') {
this._element.title = this.options.title;
} else if (this.options.title) {
this._element.title = value;
}
}
......
......@@ -9,6 +9,7 @@ import { Event } from 'vs/base/common/event';
import { IView, IViewSize } from 'vs/base/browser/ui/grid/grid';
import { IDisposable, DisposableStore } from 'vs/base/common/lifecycle';
import { Color } from 'vs/base/common/color';
import { IBoundarySashes } from 'vs/base/browser/ui/grid/gridview';
export interface CenteredViewState {
leftMarginRatio: number;
......@@ -72,6 +73,19 @@ export class CenteredViewLayout implements IDisposable {
get maximumHeight(): number { return this.view.maximumHeight; }
get onDidChange(): Event<IViewSize | undefined> { return this.view.onDidChange; }
private _boundarySashes: IBoundarySashes = {};
get boundarySashes(): IBoundarySashes { return this._boundarySashes; }
set boundarySashes(boundarySashes: IBoundarySashes) {
this._boundarySashes = boundarySashes;
if (!this.splitView) {
return;
}
this.splitView.orthogonalStartSash = boundarySashes.top;
this.splitView.orthogonalEndSash = boundarySashes.bottom;
}
layout(width: number, height: number): void {
this.width = width;
this.height = height;
......@@ -119,6 +133,8 @@ export class CenteredViewLayout implements IDisposable {
orientation: Orientation.HORIZONTAL,
styles: this.style
});
this.splitView.orthogonalStartSash = this.boundarySashes.top;
this.splitView.orthogonalEndSash = this.boundarySashes.bottom;
this.splitViewDisposables.add(this.splitView.onDidSashChange(() => {
if (this.splitView) {
......
......@@ -85,6 +85,8 @@ export namespace Event {
* Given a collection of events, returns a single event which emits
* whenever any of the provided events emit.
*/
export function any<T>(...events: Event<T>[]): Event<T>;
export function any(...events: Event<any>[]): Event<void>;
export function any<T>(...events: Event<T>[]): Event<T> {
return (listener, thisArgs = null, disposables?) => combinedDisposable(...events.map(event => event(e => listener.call(thisArgs, e), null, disposables)));
}
......
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { parseLinkedText } from 'vs/base/browser/linkedText';
suite('LinkedText', () => {
test('parses correctly', () => {
assert.deepEqual(parseLinkedText(''), []);
assert.deepEqual(parseLinkedText('hello'), ['hello']);
assert.deepEqual(parseLinkedText('hello there'), ['hello there']);
assert.deepEqual(parseLinkedText('Some message with [link text](http://link.href).'), [
'Some message with ',
{ label: 'link text', href: 'http://link.href' },
'.'
]);
assert.deepEqual(parseLinkedText('Some message with [link text](http://link.href "and a title").'), [
'Some message with ',
{ label: 'link text', href: 'http://link.href', title: 'and a title' },
'.'
]);
assert.deepEqual(parseLinkedText('Some message with [link text](random stuff).'), [
'Some message with [link text](random stuff).'
]);
assert.deepEqual(parseLinkedText('Some message with [https link](https://link.href).'), [
'Some message with ',
{ label: 'https link', href: 'https://link.href' },
'.'
]);
assert.deepEqual(parseLinkedText('Some message with [https link](https:).'), [
'Some message with [https link](https:).'
]);
assert.deepEqual(parseLinkedText('Some message with [a command](command:foobar).'), [
'Some message with ',
{ label: 'a command', href: 'command:foobar' },
'.'
]);
assert.deepEqual(parseLinkedText('Some message with [a command](command:).'), [
'Some message with [a command](command:).'
]);
assert.deepEqual(parseLinkedText('link [one](command:foo "nice") and link [two](http://foo)...'), [
'link ',
{ label: 'one', href: 'command:foo', title: 'nice' },
' and link ',
{ label: 'two', href: 'http://foo' },
'...'
]);
assert.deepEqual(parseLinkedText('link\n[one](command:foo "nice")\nand link [two](http://foo)...'), [
'link\n',
{ label: 'one', href: 'command:foo', title: 'nice' },
'\nand link ',
{ label: 'two', href: 'http://foo' },
'...'
]);
});
});
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Event } from 'vs/base/common/event';
import { IOpenerService } from 'vs/platform/opener/common/opener';
import { $ } from 'vs/base/browser/dom';
import { domEvent } from 'vs/base/browser/event';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { KeyCode } from 'vs/base/common/keyCodes';
import { Disposable } from 'vs/base/common/lifecycle';
import { Color } from 'vs/base/common/color';
export interface ILinkDescriptor {
readonly label: string;
readonly href: string;
readonly title?: string;
}
export interface ILinkStyles {
readonly textLinkForeground?: Color;
}
export class Link extends Disposable {
readonly el: HTMLAnchorElement;
private styles: ILinkStyles = {
textLinkForeground: Color.fromHex('#006AB1')
};
constructor(
link: ILinkDescriptor,
@IOpenerService openerService: IOpenerService
) {
super();
this.el = $<HTMLAnchorElement>('a', {
tabIndex: 0,
href: link.href,
title: link.title
}, link.label);
const onClick = domEvent(this.el, 'click');
const onEnterPress = Event.chain(domEvent(this.el, 'keypress'))
.map(e => new StandardKeyboardEvent(e))
.filter(e => e.keyCode === KeyCode.Enter)
.event;
const onOpen = Event.any(onClick, onEnterPress);
this._register(onOpen(_ => openerService.open(link.href)));
this.applyStyles();
}
style(styles: ILinkStyles): void {
this.styles = styles;
this.applyStyles();
}
private applyStyles(): void {
this.el.style.color = this.styles.textLinkForeground?.toString() || '';
}
}
......@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { ITheme, IThemeService } from 'vs/platform/theme/common/themeService';
import { focusBorder, inputBackground, inputForeground, ColorIdentifier, selectForeground, selectBackground, selectListBackground, selectBorder, inputBorder, foreground, editorBackground, contrastBorder, inputActiveOptionBorder, inputActiveOptionBackground, listFocusBackground, listFocusForeground, listActiveSelectionBackground, listActiveSelectionForeground, listInactiveSelectionForeground, listInactiveSelectionBackground, listInactiveFocusBackground, listHoverBackground, listHoverForeground, listDropBackground, pickerGroupBorder, pickerGroupForeground, widgetShadow, inputValidationInfoBorder, inputValidationInfoBackground, inputValidationWarningBorder, inputValidationWarningBackground, inputValidationErrorBorder, inputValidationErrorBackground, activeContrastBorder, buttonForeground, buttonBackground, buttonHoverBackground, ColorFunction, badgeBackground, badgeForeground, progressBarBackground, breadcrumbsForeground, breadcrumbsFocusForeground, breadcrumbsActiveSelectionForeground, breadcrumbsBackground, editorWidgetBorder, inputValidationInfoForeground, inputValidationWarningForeground, inputValidationErrorForeground, menuForeground, menuBackground, menuSelectionForeground, menuSelectionBackground, menuSelectionBorder, menuBorder, menuSeparatorBackground, darken, listFilterWidgetOutline, listFilterWidgetNoMatchesOutline, listFilterWidgetBackground, editorWidgetBackground, treeIndentGuidesStroke, editorWidgetForeground, simpleCheckboxBackground, simpleCheckboxBorder, simpleCheckboxForeground, ColorValue, resolveColorValue } from 'vs/platform/theme/common/colorRegistry';
import { focusBorder, inputBackground, inputForeground, ColorIdentifier, selectForeground, selectBackground, selectListBackground, selectBorder, inputBorder, foreground, editorBackground, contrastBorder, inputActiveOptionBorder, inputActiveOptionBackground, listFocusBackground, listFocusForeground, listActiveSelectionBackground, listActiveSelectionForeground, listInactiveSelectionForeground, listInactiveSelectionBackground, listInactiveFocusBackground, listHoverBackground, listHoverForeground, listDropBackground, pickerGroupBorder, pickerGroupForeground, widgetShadow, inputValidationInfoBorder, inputValidationInfoBackground, inputValidationWarningBorder, inputValidationWarningBackground, inputValidationErrorBorder, inputValidationErrorBackground, activeContrastBorder, buttonForeground, buttonBackground, buttonHoverBackground, ColorFunction, badgeBackground, badgeForeground, progressBarBackground, breadcrumbsForeground, breadcrumbsFocusForeground, breadcrumbsActiveSelectionForeground, breadcrumbsBackground, editorWidgetBorder, inputValidationInfoForeground, inputValidationWarningForeground, inputValidationErrorForeground, menuForeground, menuBackground, menuSelectionForeground, menuSelectionBackground, menuSelectionBorder, menuBorder, menuSeparatorBackground, darken, listFilterWidgetOutline, listFilterWidgetNoMatchesOutline, listFilterWidgetBackground, editorWidgetBackground, treeIndentGuidesStroke, editorWidgetForeground, simpleCheckboxBackground, simpleCheckboxBorder, simpleCheckboxForeground, ColorValue, resolveColorValue, textLinkForeground } from 'vs/platform/theme/common/colorRegistry';
import { IDisposable } from 'vs/base/common/lifecycle';
import { Color } from 'vs/base/common/color';
import { IThemable, styleFn } from 'vs/base/common/styler';
......@@ -269,6 +269,16 @@ export function attachButtonStyler(widget: IThemable, themeService: IThemeServic
} as IButtonStyleOverrides, widget);
}
export interface ILinkStyleOverrides extends IStyleOverrides {
textLinkForeground?: ColorIdentifier;
}
export function attachLinkStyler(widget: IThemable, themeService: IThemeService, style?: ILinkStyleOverrides): IDisposable {
return attachStyler(themeService, {
textLinkForeground: (style && style.textLinkForeground) || textLinkForeground,
} as ILinkStyleOverrides, widget);
}
export interface IProgressBarStyleOverrides extends IStyleOverrides {
progressBarBackground?: ColorIdentifier;
}
......
......@@ -979,6 +979,7 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro
setBoundarySashes(sashes: IBoundarySashes): void {
this.gridWidget.boundarySashes = sashes;
this.centeredLayoutWidget.boundarySashes = sashes;
}
layout(width: number, height: number): void {
......
......@@ -26,7 +26,7 @@ import { ResourceLabels, IResourceLabel } from 'vs/workbench/browser/labels';
import { ActionBar, IActionViewItemProvider, ActionViewItem } from 'vs/base/browser/ui/actionbar/actionbar';
import { URI } from 'vs/base/common/uri';
import { dirname, basename } from 'vs/base/common/resources';
import { LIGHT, FileThemeIcon, FolderThemeIcon, registerThemingParticipant, ThemeIcon } from 'vs/platform/theme/common/themeService';
import { LIGHT, FileThemeIcon, FolderThemeIcon, registerThemingParticipant, ThemeIcon, IThemeService } from 'vs/platform/theme/common/themeService';
import { FileKind } from 'vs/platform/files/common/files';
import { WorkbenchAsyncDataTree, TreeResourceNavigator } from 'vs/platform/list/browser/listService';
import { ViewPane, IViewPaneOptions } from 'vs/workbench/browser/parts/views/viewPaneContainer';
......@@ -42,6 +42,7 @@ import { FuzzyScore, createMatches } from 'vs/base/common/filters';
import { CollapseAllAction } from 'vs/base/browser/ui/tree/treeDefaults';
import { isFalsyOrWhitespace } from 'vs/base/common/strings';
import { SIDE_BAR_BACKGROUND, PANEL_BACKGROUND } from 'vs/workbench/common/theme';
import { IOpenerService } from 'vs/platform/opener/common/opener';
export class CustomTreeViewPane extends ViewPane {
......@@ -56,8 +57,10 @@ export class CustomTreeViewPane extends ViewPane {
@IContextKeyService contextKeyService: IContextKeyService,
@IViewDescriptorService viewDescriptorService: IViewDescriptorService,
@IInstantiationService instantiationService: IInstantiationService,
@IOpenerService openerService: IOpenerService,
@IThemeService themeService: IThemeService,
) {
super({ ...(options as IViewPaneOptions), ariaHeaderLabel: options.title, titleMenuId: MenuId.ViewTitle }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService);
super({ ...(options as IViewPaneOptions), ariaHeaderLabel: options.title, titleMenuId: MenuId.ViewTitle }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService);
const { treeView } = (<ITreeViewDescriptor>Registry.as<IViewsRegistry>(Extensions.ViewsRegistry).getView(options.id));
this.treeView = treeView;
this._register(this.treeView.onDidChangeActions(() => this.updateActions(), this));
......@@ -73,6 +76,8 @@ export class CustomTreeViewPane extends ViewPane {
}
renderBody(container: HTMLElement): void {
super.renderBody(container);
if (this.treeView instanceof CustomTreeView) {
this.treeView.show(container);
}
......
......@@ -71,6 +71,26 @@
display: none;
}
.monaco-workbench .pane > .pane-body > .empty-view {
width: 100%;
height: 100%;
padding: 0 20px 0 20px;
position: absolute;
box-sizing: border-box;
}
.monaco-workbench .pane > .pane-body:not(.empty) > .empty-view,
.monaco-workbench .pane > .pane-body.empty > :not(.empty-view) {
display: none;
}
.monaco-workbench .pane > .pane-body > .empty-view .monaco-button {
max-width: 260px;
margin-left: auto;
margin-right: auto;
display: block;
}
.customview-tree .monaco-list-row .monaco-tl-contents.align-icon-with-twisty::before {
display: none;
}
......
......@@ -7,10 +7,10 @@ import 'vs/css!./media/paneviewlet';
import * as nls from 'vs/nls';
import { Event, Emitter } from 'vs/base/common/event';
import { ColorIdentifier } from 'vs/platform/theme/common/colorRegistry';
import { attachStyler, IColorMapping } from 'vs/platform/theme/common/styler';
import { attachStyler, IColorMapping, attachButtonStyler, attachLinkStyler } from 'vs/platform/theme/common/styler';
import { SIDE_BAR_DRAG_AND_DROP_BACKGROUND, SIDE_BAR_SECTION_HEADER_FOREGROUND, SIDE_BAR_SECTION_HEADER_BACKGROUND, SIDE_BAR_SECTION_HEADER_BORDER, PANEL_BACKGROUND, SIDE_BAR_BACKGROUND } from 'vs/workbench/common/theme';
import { append, $, trackFocus, toggleClass, EventType, isAncestor, Dimension, addDisposableListener } from 'vs/base/browser/dom';
import { IDisposable, combinedDisposable, dispose, toDisposable } from 'vs/base/common/lifecycle';
import { append, $, trackFocus, toggleClass, EventType, isAncestor, Dimension, addDisposableListener, removeClass, addClass } from 'vs/base/browser/dom';
import { IDisposable, combinedDisposable, dispose, toDisposable, Disposable, DisposableStore } from 'vs/base/common/lifecycle';
import { firstIndex } from 'vs/base/common/arrays';
import { IAction, IActionRunner, ActionRunner } from 'vs/base/common/actions';
import { IActionViewItem, ActionsOrientation, Separator } from 'vs/base/browser/ui/actionbar/actionbar';
......@@ -25,7 +25,7 @@ import { PaneView, IPaneViewOptions, IPaneOptions, Pane, DefaultPaneDndControlle
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
import { Extensions as ViewContainerExtensions, IView, FocusedViewContext, IViewContainersRegistry, IViewDescriptor, ViewContainer, IViewDescriptorService, ViewContainerLocation, IViewPaneContainer } from 'vs/workbench/common/views';
import { Extensions as ViewContainerExtensions, IView, FocusedViewContext, IViewContainersRegistry, IViewDescriptor, ViewContainer, IViewDescriptorService, ViewContainerLocation, IViewPaneContainer, IViewsRegistry } from 'vs/workbench/common/views';
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { assertIsDefined } from 'vs/base/common/types';
......@@ -38,6 +38,10 @@ import { Component } from 'vs/workbench/common/component';
import { MenuId, MenuItemAction } from 'vs/platform/actions/common/actions';
import { ContextAwareMenuEntryActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { ViewMenuActions } from 'vs/workbench/browser/parts/views/viewMenuActions';
import { parseLinkedText } from 'vs/base/browser/linkedText';
import { IOpenerService } from 'vs/platform/opener/common/opener';
import { Button } from 'vs/base/browser/ui/button/button';
import { Link } from 'vs/platform/opener/browser/link';
export interface IPaneColors extends IColorMapping {
dropBackground?: ColorIdentifier;
......@@ -54,6 +58,8 @@ export interface IViewPaneOptions extends IPaneOptions {
titleMenuId?: MenuId;
}
const viewsRegistry = Registry.as<IViewsRegistry>(ViewContainerExtensions.ViewsRegistry);
export abstract class ViewPane extends Pane implements IView {
private static readonly AlwaysShowActionsConfig = 'workbench.view.alwaysShowHeaderActions';
......@@ -70,6 +76,9 @@ export abstract class ViewPane extends Pane implements IView {
protected _onDidChangeTitleArea = this._register(new Emitter<void>());
readonly onDidChangeTitleArea: Event<void> = this._onDidChangeTitleArea.event;
protected _onDidChangeEmptyState = this._register(new Emitter<void>());
readonly onDidChangeEmptyState: Event<void> = this._onDidChangeEmptyState.event;
private focusedViewContextKey: IContextKey<string>;
private _isVisible: boolean = false;
......@@ -85,6 +94,10 @@ export abstract class ViewPane extends Pane implements IView {
private titleContainer?: HTMLElement;
protected twistiesContainer?: HTMLElement;
private bodyContainer!: HTMLElement;
private emptyViewContainer!: HTMLElement;
private emptyViewDisposable: IDisposable = Disposable.None;
constructor(
options: IViewPaneOptions,
@IKeybindingService protected keybindingService: IKeybindingService,
......@@ -93,6 +106,8 @@ export abstract class ViewPane extends Pane implements IView {
@IContextKeyService contextKeyService: IContextKeyService,
@IViewDescriptorService protected viewDescriptorService: IViewDescriptorService,
@IInstantiationService protected instantiationService: IInstantiationService,
@IOpenerService protected openerService: IOpenerService,
@IThemeService protected themeService: IThemeService,
) {
super(options);
......@@ -189,6 +204,22 @@ export abstract class ViewPane extends Pane implements IView {
this._onDidChangeTitleArea.fire();
}
protected renderBody(container: HTMLElement): void {
this.bodyContainer = container;
this.emptyViewContainer = append(container, $('.empty-view', { tabIndex: 0 }));
// we should update our empty state whenever
const onEmptyViewContentChange = Event.any(
// the registry changes
Event.map(Event.filter(viewsRegistry.onDidChangeEmptyViewContent, id => id === this.id), () => this.isEmpty()),
// or the view's empty state changes
Event.latch(Event.map(this.onDidChangeEmptyState, () => this.isEmpty()))
);
this._register(onEmptyViewContentChange(this.updateEmptyState, this));
this.updateEmptyState(this.isEmpty());
}
protected getProgressLocation(): string {
return this.viewDescriptorService.getViewContainer(this.id)!.id;
}
......@@ -254,6 +285,66 @@ export abstract class ViewPane extends Pane implements IView {
saveState(): void {
// Subclasses to implement for saving state
}
private updateEmptyState(isEmpty: boolean): void {
this.emptyViewDisposable.dispose();
if (!isEmpty) {
removeClass(this.bodyContainer, 'empty');
this.emptyViewContainer.innerHTML = '';
return;
}
const contents = viewsRegistry.getEmptyViewContent(this.id);
if (contents.length === 0) {
removeClass(this.bodyContainer, 'empty');
this.emptyViewContainer.innerHTML = '';
return;
}
const disposables = new DisposableStore();
addClass(this.bodyContainer, 'empty');
this.emptyViewContainer.innerHTML = '';
for (const { content } of contents) {
const lines = content.split('\n');
for (let line of lines) {
line = line.trim();
if (!line) {
continue;
}
const p = append(this.emptyViewContainer, $('p'));
const linkedText = parseLinkedText(line);
for (const node of linkedText) {
if (typeof node === 'string') {
append(p, document.createTextNode(node));
} else if (linkedText.length === 1) {
const button = new Button(p, { title: node.title });
button.label = node.label;
button.onDidClick(_ => this.openerService.open(node.href), null, disposables);
disposables.add(button);
disposables.add(attachButtonStyler(button, this.themeService));
} else {
const link = this.instantiationService.createInstance(Link, node);
append(p, link.el);
disposables.add(link);
disposables.add(attachLinkStyler(link, this.themeService));
}
}
}
}
this.emptyViewDisposable = disposables;
}
isEmpty(): boolean {
return false;
}
}
export interface IViewPaneContainerOptions extends IPaneViewOptions {
......
......@@ -10,7 +10,7 @@ import { ContextKeyExpr, RawContextKey } from 'vs/platform/contextkey/common/con
import { localize } from 'vs/nls';
import { IViewlet } from 'vs/workbench/common/viewlet';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { IDisposable, Disposable } from 'vs/base/common/lifecycle';
import { IDisposable, Disposable, toDisposable } from 'vs/base/common/lifecycle';
import { ThemeIcon } from 'vs/platform/theme/common/themeService';
import { values, keys, getOrSet } from 'vs/base/common/map';
import { Registry } from 'vs/platform/registry/common/platform';
......@@ -19,6 +19,7 @@ import { IAction, IActionViewItem } from 'vs/base/common/actions';
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
import { flatten } from 'vs/base/common/arrays';
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
import { SetMap } from 'vs/base/common/collections';
export const TEST_VIEW_CONTAINER_ID = 'workbench.view.extension.test';
......@@ -210,6 +211,10 @@ export interface IViewDescriptorCollection extends IDisposable {
readonly allViewDescriptors: IViewDescriptor[];
}
export interface IViewContentDescriptor {
readonly content: string;
}
export interface IViewsRegistry {
readonly onViewsRegistered: Event<{ views: IViewDescriptor[], viewContainer: ViewContainer }>;
......@@ -229,6 +234,10 @@ export interface IViewsRegistry {
getView(id: string): IViewDescriptor | null;
getViewContainer(id: string): ViewContainer | null;
readonly onDidChangeEmptyViewContent: Event<string>;
registerEmptyViewContent(id: string, viewContent: IViewContentDescriptor): IDisposable;
getEmptyViewContent(id: string): IViewContentDescriptor[];
}
class ViewsRegistry extends Disposable implements IViewsRegistry {
......@@ -242,8 +251,12 @@ class ViewsRegistry extends Disposable implements IViewsRegistry {
private readonly _onDidChangeContainer: Emitter<{ views: IViewDescriptor[], from: ViewContainer, to: ViewContainer }> = this._register(new Emitter<{ views: IViewDescriptor[], from: ViewContainer, to: ViewContainer }>());
readonly onDidChangeContainer: Event<{ views: IViewDescriptor[], from: ViewContainer, to: ViewContainer }> = this._onDidChangeContainer.event;
private readonly _onDidChangeEmptyViewContent: Emitter<string> = this._register(new Emitter<string>());
readonly onDidChangeEmptyViewContent: Event<string> = this._onDidChangeEmptyViewContent.event;
private _viewContainers: ViewContainer[] = [];
private _views: Map<ViewContainer, IViewDescriptor[]> = new Map<ViewContainer, IViewDescriptor[]>();
private _emptyViewContents = new SetMap<string, IViewContentDescriptor>();
registerViews(views: IViewDescriptor[], viewContainer: ViewContainer): void {
this.addViews(views, viewContainer);
......@@ -293,6 +306,22 @@ class ViewsRegistry extends Disposable implements IViewsRegistry {
return null;
}
registerEmptyViewContent(id: string, viewContent: IViewContentDescriptor): IDisposable {
this._emptyViewContents.add(id, viewContent);
this._onDidChangeEmptyViewContent.fire(id);
return toDisposable(() => {
this._emptyViewContents.delete(id, viewContent);
this._onDidChangeEmptyViewContent.fire(id);
});
}
getEmptyViewContent(id: string): IViewContentDescriptor[] {
const result: IViewContentDescriptor[] = [];
this._emptyViewContents.forEach(id, descriptor => result.push(descriptor));
return result;
}
private addViews(viewDescriptors: IViewDescriptor[], viewContainer: ViewContainer): void {
let views = this._views.get(viewContainer);
if (!views) {
......
......@@ -9,7 +9,7 @@ import { WorkspaceEdit } from 'vs/editor/common/modes';
import { BulkEditElement, BulkEditDelegate, TextEditElementRenderer, FileElementRenderer, BulkEditDataSource, BulkEditIdentityProvider, FileElement, TextEditElement, BulkEditAccessibilityProvider, BulkEditAriaProvider, CategoryElementRenderer, BulkEditNaviLabelProvider, CategoryElement } from 'vs/workbench/contrib/bulkEdit/browser/bulkEditTree';
import { FuzzyScore } from 'vs/base/common/filters';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { registerThemingParticipant, ITheme, ICssStyleCollector } from 'vs/platform/theme/common/themeService';
import { registerThemingParticipant, ITheme, ICssStyleCollector, IThemeService } from 'vs/platform/theme/common/themeService';
import { diffInserted, diffRemoved } from 'vs/platform/theme/common/colorRegistry';
import { localize } from 'vs/nls';
import { DisposableStore } from 'vs/base/common/lifecycle';
......@@ -37,6 +37,7 @@ import { ITextEditorOptions } from 'vs/platform/editor/common/editor';
import type { IAsyncDataTreeViewState } from 'vs/base/browser/ui/tree/asyncDataTree';
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
import { IViewDescriptorService } from 'vs/workbench/common/views';
import { IOpenerService } from 'vs/platform/opener/common/opener';
const enum State {
Data = 'data',
......@@ -83,10 +84,12 @@ export class BulkEditPane extends ViewPane {
@IKeybindingService keybindingService: IKeybindingService,
@IContextMenuService contextMenuService: IContextMenuService,
@IConfigurationService configurationService: IConfigurationService,
@IOpenerService openerService: IOpenerService,
@IThemeService themeService: IThemeService,
) {
super(
{ ...options, titleMenuId: MenuId.BulkEditTitle },
keybindingService, contextMenuService, configurationService, _contextKeyService, viewDescriptorService, _instaService
keybindingService, contextMenuService, configurationService, _contextKeyService, viewDescriptorService, _instaService, openerService, themeService
);
this.element.classList.add('bulk-edit-panel', 'show-file-icons');
......@@ -101,6 +104,7 @@ export class BulkEditPane extends ViewPane {
}
protected renderBody(parent: HTMLElement): void {
super.renderBody(parent);
const resourceLabels = this._instaService.createInstance(
ResourceLabels,
......
......@@ -35,6 +35,7 @@ import { SIDE_BAR_BACKGROUND } from 'vs/workbench/common/theme';
import { Gesture } from 'vs/base/browser/touch';
import { IViewDescriptorService } from 'vs/workbench/common/views';
import { TextEditorSelectionRevealType } from 'vs/platform/editor/common/editor';
import { IOpenerService } from 'vs/platform/opener/common/opener';
const $ = dom.$;
......@@ -64,20 +65,23 @@ export class BreakpointsView extends ViewPane {
@IDebugService private readonly debugService: IDebugService,
@IKeybindingService keybindingService: IKeybindingService,
@IInstantiationService instantiationService: IInstantiationService,
@IThemeService private readonly themeService: IThemeService,
@IThemeService themeService: IThemeService,
@IEditorService private readonly editorService: IEditorService,
@IContextViewService private readonly contextViewService: IContextViewService,
@IConfigurationService configurationService: IConfigurationService,
@IViewDescriptorService viewDescriptorService: IViewDescriptorService,
@IContextKeyService contextKeyService: IContextKeyService,
@IOpenerService openerService: IOpenerService,
) {
super({ ...(options as IViewPaneOptions), ariaHeaderLabel: nls.localize('breakpointsSection', "Breakpoints Section") }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService);
super({ ...(options as IViewPaneOptions), ariaHeaderLabel: nls.localize('breakpointsSection', "Breakpoints Section") }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService);
this.minimumBodySize = this.maximumBodySize = getExpandedBodySize(this.debugService.getModel());
this._register(this.debugService.getModel().onDidChangeBreakpoints(() => this.onBreakpointsChange()));
}
public renderBody(container: HTMLElement): void {
super.renderBody(container);
dom.addClass(container, 'debug-breakpoints');
const delegate = new BreakpointsDelegate(this.debugService);
......
......@@ -36,6 +36,8 @@ import { ICommandService } from 'vs/platform/commands/common/commands';
import { CollapseAction } from 'vs/workbench/browser/viewlet';
import { SIDE_BAR_BACKGROUND } from 'vs/workbench/common/theme';
import { IViewDescriptorService } from 'vs/workbench/common/views';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { IOpenerService } from 'vs/platform/opener/common/opener';
const $ = dom.$;
......@@ -98,8 +100,10 @@ export class CallStackView extends ViewPane {
@IConfigurationService configurationService: IConfigurationService,
@IMenuService menuService: IMenuService,
@IContextKeyService readonly contextKeyService: IContextKeyService,
@IOpenerService openerService: IOpenerService,
@IThemeService themeService: IThemeService,
) {
super({ ...(options as IViewPaneOptions), ariaHeaderLabel: nls.localize('callstackSection', "Call Stack Section") }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService);
super({ ...(options as IViewPaneOptions), ariaHeaderLabel: nls.localize('callstackSection', "Call Stack Section") }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService);
this.callStackItemType = CONTEXT_CALLSTACK_ITEM_TYPE.bindTo(contextKeyService);
this.contributedContextMenu = menuService.createMenu(MenuId.DebugCallStackContext, contextKeyService);
......@@ -151,6 +155,8 @@ export class CallStackView extends ViewPane {
}
renderBody(container: HTMLElement): void {
super.renderBody(container);
dom.addClass(container, 'debug-call-stack');
const treeContainer = renderViewTree(container);
......
......@@ -38,6 +38,8 @@ import { SIDE_BAR_BACKGROUND } from 'vs/workbench/common/theme';
import type { ICompressedTreeNode } from 'vs/base/browser/ui/tree/compressedObjectTreeModel';
import type { ICompressibleTreeRenderer } from 'vs/base/browser/ui/tree/objectTree';
import { IViewDescriptorService } from 'vs/workbench/common/views';
import { IOpenerService } from 'vs/platform/opener/common/opener';
import { IThemeService } from 'vs/platform/theme/common/themeService';
const NEW_STYLE_COMPRESS = true;
......@@ -423,13 +425,17 @@ export class LoadedScriptsView extends ViewPane {
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService,
@IEnvironmentService private readonly environmentService: IEnvironmentService,
@IDebugService private readonly debugService: IDebugService,
@ILabelService private readonly labelService: ILabelService
@ILabelService private readonly labelService: ILabelService,
@IOpenerService openerService: IOpenerService,
@IThemeService themeService: IThemeService,
) {
super({ ...(options as IViewPaneOptions), ariaHeaderLabel: nls.localize('loadedScriptsSection', "Loaded Scripts Section") }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService);
super({ ...(options as IViewPaneOptions), ariaHeaderLabel: nls.localize('loadedScriptsSection', "Loaded Scripts Section") }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService);
this.loadedScriptsItemType = CONTEXT_LOADED_SCRIPTS_ITEM_TYPE.bindTo(contextKeyService);
}
renderBody(container: HTMLElement): void {
super.renderBody(container);
dom.addClass(container, 'debug-loaded-scripts');
dom.addClass(container, 'show-file-icons');
......
......@@ -56,6 +56,7 @@ import { localize } from 'vs/nls';
import { ViewPane, IViewPaneOptions } from 'vs/workbench/browser/parts/views/viewPaneContainer';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { IViewsService, IViewDescriptorService } from 'vs/workbench/common/views';
import { IOpenerService } from 'vs/platform/opener/common/opener';
const $ = dom.$;
......@@ -96,7 +97,7 @@ export class Repl extends ViewPane implements IHistoryNavigationWidget {
@IDebugService private readonly debugService: IDebugService,
@IInstantiationService instantiationService: IInstantiationService,
@IStorageService private readonly storageService: IStorageService,
@IThemeService protected themeService: IThemeService,
@IThemeService themeService: IThemeService,
@IModelService private readonly modelService: IModelService,
@IContextKeyService private readonly contextKeyService: IContextKeyService,
@ICodeEditorService codeEditorService: ICodeEditorService,
......@@ -106,9 +107,10 @@ export class Repl extends ViewPane implements IHistoryNavigationWidget {
@ITextResourcePropertiesService private readonly textResourcePropertiesService: ITextResourcePropertiesService,
@IClipboardService private readonly clipboardService: IClipboardService,
@IEditorService private readonly editorService: IEditorService,
@IKeybindingService keybindingService: IKeybindingService
@IKeybindingService keybindingService: IKeybindingService,
@IOpenerService openerService: IOpenerService,
) {
super({ ...(options as IViewPaneOptions), id: REPL_VIEW_ID, ariaHeaderLabel: localize('debugConsole', "Debug Console") }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService);
super({ ...(options as IViewPaneOptions), id: REPL_VIEW_ID, ariaHeaderLabel: localize('debugConsole', "Debug Console") }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService);
this.history = new HistoryNavigator(JSON.parse(this.storageService.get(HISTORY_STORAGE_KEY, StorageScope.WORKSPACE, '[]')), 50);
codeEditorService.registerDecorationType(DECORATION_KEY, {});
......@@ -431,6 +433,8 @@ export class Repl extends ViewPane implements IHistoryNavigationWidget {
// --- Creation
protected renderBody(parent: HTMLElement): void {
super.renderBody(parent);
this.container = dom.append(parent, $('.repl'));
const treeContainer = dom.append(this.container, $('.repl-tree'));
this.createReplInput(this.container);
......
......@@ -26,6 +26,7 @@ import { KeyCode } from 'vs/base/common/keyCodes';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IViewDescriptorService } from 'vs/workbench/common/views';
import { IOpenerService } from 'vs/platform/opener/common/opener';
const $ = dom.$;
interface DebugStartMetrics {
......@@ -63,7 +64,7 @@ export class StartView extends ViewPane {
constructor(
options: IViewletViewOptions,
@IThemeService private readonly themeService: IThemeService,
@IThemeService themeService: IThemeService,
@IKeybindingService keybindingService: IKeybindingService,
@IContextMenuService contextMenuService: IContextMenuService,
@IConfigurationService configurationService: IConfigurationService,
......@@ -75,9 +76,10 @@ export class StartView extends ViewPane {
@IFileDialogService private readonly dialogService: IFileDialogService,
@IInstantiationService instantiationService: IInstantiationService,
@IViewDescriptorService viewDescriptorService: IViewDescriptorService,
@ITelemetryService private readonly telemetryService: ITelemetryService
@ITelemetryService private readonly telemetryService: ITelemetryService,
@IOpenerService openerService: IOpenerService,
) {
super({ ...(options as IViewPaneOptions), ariaHeaderLabel: localize('debugStart', "Debug Start Section") }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService);
super({ ...(options as IViewPaneOptions), ariaHeaderLabel: localize('debugStart', "Debug Start Section") }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService);
this._register(editorService.onDidActiveEditorChange(() => this.updateView()));
this._register(this.debugService.getConfigurationManager().onDidRegisterDebugger(() => this.updateView()));
}
......@@ -156,6 +158,8 @@ export class StartView extends ViewPane {
}
protected renderBody(container: HTMLElement): void {
super.renderBody(container);
this.firstMessageContainer = $('.top-section');
container.appendChild(this.firstMessageContainer);
......
......@@ -32,6 +32,8 @@ import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { dispose } from 'vs/base/common/lifecycle';
import { SIDE_BAR_BACKGROUND } from 'vs/workbench/common/theme';
import { IViewDescriptorService } from 'vs/workbench/common/views';
import { IOpenerService } from 'vs/platform/opener/common/opener';
import { IThemeService } from 'vs/platform/theme/common/themeService';
const $ = dom.$;
let forgetScopes = true;
......@@ -54,9 +56,11 @@ export class VariablesView extends ViewPane {
@IInstantiationService instantiationService: IInstantiationService,
@IViewDescriptorService viewDescriptorService: IViewDescriptorService,
@IClipboardService private readonly clipboardService: IClipboardService,
@IContextKeyService contextKeyService: IContextKeyService
@IContextKeyService contextKeyService: IContextKeyService,
@IOpenerService openerService: IOpenerService,
@IThemeService themeService: IThemeService,
) {
super({ ...(options as IViewPaneOptions), ariaHeaderLabel: nls.localize('variablesSection', "Variables Section") }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService);
super({ ...(options as IViewPaneOptions), ariaHeaderLabel: nls.localize('variablesSection', "Variables Section") }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService);
// Use scheduler to prevent unnecessary flashing
this.onFocusStackFrameScheduler = new RunOnceScheduler(async () => {
......@@ -85,6 +89,8 @@ export class VariablesView extends ViewPane {
}
renderBody(container: HTMLElement): void {
super.renderBody(container);
dom.addClass(container, 'debug-variables');
const treeContainer = renderViewTree(container);
......
......@@ -32,6 +32,8 @@ import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { dispose } from 'vs/base/common/lifecycle';
import { SIDE_BAR_BACKGROUND } from 'vs/workbench/common/theme';
import { IViewDescriptorService } from 'vs/workbench/common/views';
import { IOpenerService } from 'vs/platform/opener/common/opener';
import { IThemeService } from 'vs/platform/theme/common/themeService';
const MAX_VALUE_RENDER_LENGTH_IN_VIEWLET = 1024;
let ignoreVariableSetEmitter = false;
......@@ -52,8 +54,10 @@ export class WatchExpressionsView extends ViewPane {
@IViewDescriptorService viewDescriptorService: IViewDescriptorService,
@IConfigurationService configurationService: IConfigurationService,
@IContextKeyService contextKeyService: IContextKeyService,
@IOpenerService openerService: IOpenerService,
@IThemeService themeService: IThemeService,
) {
super({ ...(options as IViewPaneOptions), ariaHeaderLabel: nls.localize('watchExpressionsSection', "Watch Expressions Section") }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService);
super({ ...(options as IViewPaneOptions), ariaHeaderLabel: nls.localize('watchExpressionsSection', "Watch Expressions Section") }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService);
this.onWatchExpressionsUpdatedScheduler = new RunOnceScheduler(() => {
this.needsRefresh = false;
......@@ -62,6 +66,8 @@ export class WatchExpressionsView extends ViewPane {
}
renderBody(container: HTMLElement): void {
super.renderBody(container);
dom.addClass(container, 'debug-watch');
const treeContainer = renderViewTree(container);
......
......@@ -50,6 +50,7 @@ import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { SIDE_BAR_BACKGROUND } from 'vs/workbench/common/theme';
import { IMenuService } from 'vs/platform/actions/common/actions';
import { IViewDescriptorService } from 'vs/workbench/common/views';
import { IOpenerService } from 'vs/platform/opener/common/opener';
// Extensions that are automatically classified as Programming Language extensions, but should be Feature extensions
const FORCE_FEATURE_EXTENSIONS = ['vscode.git', 'vscode.search-result'];
......@@ -96,7 +97,7 @@ export class ExtensionsListView extends ViewPane {
@IKeybindingService keybindingService: IKeybindingService,
@IContextMenuService contextMenuService: IContextMenuService,
@IInstantiationService protected instantiationService: IInstantiationService,
@IThemeService private readonly themeService: IThemeService,
@IThemeService themeService: IThemeService,
@IExtensionService private readonly extensionService: IExtensionService,
@IExtensionsWorkbenchService protected extensionsWorkbenchService: IExtensionsWorkbenchService,
@IEditorService private readonly editorService: IEditorService,
......@@ -111,8 +112,9 @@ export class ExtensionsListView extends ViewPane {
@IContextKeyService private readonly contextKeyService: IContextKeyService,
@IViewDescriptorService viewDescriptorService: IViewDescriptorService,
@IMenuService private readonly menuService: IMenuService,
@IOpenerService openerService: IOpenerService,
) {
super({ ...(options as IViewPaneOptions), ariaHeaderLabel: options.title, showActionsAlways: true }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService);
super({ ...(options as IViewPaneOptions), ariaHeaderLabel: options.title, showActionsAlways: true }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService);
this.server = options.server;
}
......@@ -125,6 +127,8 @@ export class ExtensionsListView extends ViewPane {
}
renderBody(container: HTMLElement): void {
super.renderBody(container);
const extensionsList = append(container, $('.extensions-list'));
const messageContainer = append(container, $('.message-container'));
const messageSeverityIcon = append(messageContainer, $(''));
......@@ -870,7 +874,6 @@ export class ServerExtensionsView extends ExtensionsListView {
@IContextMenuService contextMenuService: IContextMenuService,
@IViewDescriptorService viewDescriptorService: IViewDescriptorService,
@IInstantiationService instantiationService: IInstantiationService,
@IThemeService themeService: IThemeService,
@IExtensionService extensionService: IExtensionService,
@IEditorService editorService: IEditorService,
@IExtensionTipsService tipsService: IExtensionTipsService,
......@@ -884,9 +887,11 @@ export class ServerExtensionsView extends ExtensionsListView {
@IProductService productService: IProductService,
@IContextKeyService contextKeyService: IContextKeyService,
@IMenuService menuService: IMenuService,
@IOpenerService openerService: IOpenerService,
@IThemeService themeService: IThemeService,
) {
options.server = server;
super(options, notificationService, keybindingService, contextMenuService, instantiationService, themeService, extensionService, extensionsWorkbenchService, editorService, tipsService, telemetryService, configurationService, contextService, experimentService, workbenchThemeService, extensionManagementServerService, productService, contextKeyService, viewDescriptorService, menuService);
super(options, notificationService, keybindingService, contextMenuService, instantiationService, themeService, extensionService, extensionsWorkbenchService, editorService, tipsService, telemetryService, configurationService, contextService, experimentService, workbenchThemeService, extensionManagementServerService, productService, contextKeyService, viewDescriptorService, menuService, openerService);
this._register(onDidChangeTitle(title => this.updateTitle(title)));
}
......
......@@ -26,6 +26,7 @@ import { Schemas } from 'vs/base/common/network';
import { isWeb } from 'vs/base/common/platform';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IViewDescriptorService } from 'vs/workbench/common/views';
import { IOpenerService } from 'vs/platform/opener/common/opener';
export class EmptyView extends ViewPane {
......@@ -37,7 +38,7 @@ export class EmptyView extends ViewPane {
constructor(
options: IViewletViewOptions,
@IThemeService private readonly themeService: IThemeService,
@IThemeService themeService: IThemeService,
@IViewDescriptorService viewDescriptorService: IViewDescriptorService,
@IInstantiationService instantiationService: IInstantiationService,
@IKeybindingService keybindingService: IKeybindingService,
......@@ -46,14 +47,17 @@ export class EmptyView extends ViewPane {
@IConfigurationService configurationService: IConfigurationService,
@IWorkbenchEnvironmentService private environmentService: IWorkbenchEnvironmentService,
@ILabelService private labelService: ILabelService,
@IContextKeyService contextKeyService: IContextKeyService
@IContextKeyService contextKeyService: IContextKeyService,
@IOpenerService openerService: IOpenerService
) {
super({ ...(options as IViewPaneOptions), ariaHeaderLabel: nls.localize('explorerSection', "Files Explorer Section") }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService);
super({ ...(options as IViewPaneOptions), ariaHeaderLabel: nls.localize('explorerSection', "Files Explorer Section") }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService);
this._register(this.contextService.onDidChangeWorkbenchState(() => this.setLabels()));
this._register(this.labelService.onDidChangeFormatters(() => this.setLabels()));
}
protected renderBody(container: HTMLElement): void {
super.renderBody(container);
DOM.addClass(container, 'explorer-empty-view');
container.tabIndex = 0;
......
......@@ -56,6 +56,7 @@ import { ColorValue, listDropBackground } from 'vs/platform/theme/common/colorRe
import { Color } from 'vs/base/common/color';
import { SIDE_BAR_BACKGROUND } from 'vs/workbench/common/theme';
import { IViewDescriptorService } from 'vs/workbench/common/views';
import { IOpenerService } from 'vs/platform/opener/common/opener';
interface IExplorerViewColors extends IColorMapping {
listDropBackground?: ColorValue | undefined;
......@@ -162,15 +163,16 @@ export class ExplorerView extends ViewPane {
@IConfigurationService configurationService: IConfigurationService,
@IDecorationsService private readonly decorationService: IDecorationsService,
@ILabelService private readonly labelService: ILabelService,
@IThemeService private readonly themeService: IWorkbenchThemeService,
@IThemeService protected themeService: IWorkbenchThemeService,
@IMenuService private readonly menuService: IMenuService,
@ITelemetryService private readonly telemetryService: ITelemetryService,
@IExplorerService private readonly explorerService: IExplorerService,
@IStorageService private readonly storageService: IStorageService,
@IClipboardService private clipboardService: IClipboardService,
@IFileService private readonly fileService: IFileService
@IFileService private readonly fileService: IFileService,
@IOpenerService openerService: IOpenerService,
) {
super({ ...(options as IViewPaneOptions), id: ExplorerView.ID, ariaHeaderLabel: nls.localize('explorerSection', "Files Explorer Section") }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService);
super({ ...(options as IViewPaneOptions), id: ExplorerView.ID, ariaHeaderLabel: nls.localize('explorerSection', "Files Explorer Section") }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService);
this.resourceContext = instantiationService.createInstance(ResourceContextKey);
this._register(this.resourceContext);
......@@ -239,6 +241,8 @@ export class ExplorerView extends ViewPane {
}
renderBody(container: HTMLElement): void {
super.renderBody(container);
const treeContainer = DOM.append(container, DOM.$('.explorer-folders-view'));
this.styleElement = DOM.createStyleSheet(treeContainer);
......
......@@ -45,6 +45,7 @@ import { IWorkingCopyService, IWorkingCopy, WorkingCopyCapabilities } from 'vs/w
import { SIDE_BAR_BACKGROUND } from 'vs/workbench/common/theme';
import { AutoSaveMode, IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService';
import { IViewDescriptorService } from 'vs/workbench/common/views';
import { IOpenerService } from 'vs/platform/opener/common/opener';
const $ = dom.$;
......@@ -76,16 +77,17 @@ export class OpenEditorsView extends ViewPane {
@IConfigurationService configurationService: IConfigurationService,
@IKeybindingService keybindingService: IKeybindingService,
@IContextKeyService private readonly contextKeyService: IContextKeyService,
@IThemeService private readonly themeService: IThemeService,
@IThemeService themeService: IThemeService,
@ITelemetryService private readonly telemetryService: ITelemetryService,
@IMenuService private readonly menuService: IMenuService,
@IWorkingCopyService private readonly workingCopyService: IWorkingCopyService,
@IFilesConfigurationService private readonly filesConfigurationService: IFilesConfigurationService
@IFilesConfigurationService private readonly filesConfigurationService: IFilesConfigurationService,
@IOpenerService openerService: IOpenerService,
) {
super({
...(options as IViewPaneOptions),
ariaHeaderLabel: nls.localize({ key: 'openEditosrSection', comment: ['Open is an adjective'] }, "Open Editors Section"),
}, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService);
}, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService);
this.structuralRefreshDelay = 0;
this.listRefreshScheduler = new RunOnceScheduler(() => {
......@@ -202,6 +204,8 @@ export class OpenEditorsView extends ViewPane {
}
renderBody(container: HTMLElement): void {
super.renderBody(container);
dom.addClass(container, 'explorer-open-editors');
dom.addClass(container, 'show-file-icons');
......
......@@ -49,6 +49,7 @@ import { KeyCode } from 'vs/base/common/keyCodes';
import { editorLightBulbForeground, editorLightBulbAutoFixForeground } from 'vs/platform/theme/common/colorRegistry';
import { ViewPane, IViewPaneOptions } from 'vs/workbench/browser/parts/views/viewPaneContainer';
import { IViewDescriptorService } from 'vs/workbench/common/views';
import { IOpenerService } from 'vs/platform/opener/common/opener';
function createResourceMarkersIterator(resourceMarkers: ResourceMarkers): Iterator<ITreeElement<TreeElement>> {
const markersIt = Iterator.fromArray(resourceMarkers.markers);
......@@ -104,8 +105,10 @@ export class MarkersView extends ViewPane implements IMarkerFilterController {
@IMenuService private readonly menuService: IMenuService,
@IKeybindingService keybindingService: IKeybindingService,
@IStorageService storageService: IStorageService,
@IOpenerService openerService: IOpenerService,
@IThemeService themeService: IThemeService,
) {
super({ ...(options as IViewPaneOptions), id: Constants.MARKERS_VIEW_ID, ariaHeaderLabel: Messages.MARKERS_PANEL_TITLE_PROBLEMS }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService);
super({ ...(options as IViewPaneOptions), id: Constants.MARKERS_VIEW_ID, ariaHeaderLabel: Messages.MARKERS_PANEL_TITLE_PROBLEMS }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService);
this.panelFoucusContextKey = Constants.MarkerViewFocusContextKey.bindTo(contextKeyService);
this.panelState = new Memento(Constants.MARKERS_VIEW_STORAGE_ID, storageService).getMemento(StorageScope.WORKSPACE);
this.markersViewModel = this._register(instantiationService.createInstance(MarkersViewModel, this.panelState['multiline']));
......@@ -129,6 +132,7 @@ export class MarkersView extends ViewPane implements IMarkerFilterController {
}
public renderBody(parent: HTMLElement): void {
super.renderBody(parent);
dom.addClass(parent, 'markers-panel');
......@@ -185,7 +189,7 @@ export class MarkersView extends ViewPane implements IMarkerFilterController {
return;
}
if (this.isEmpty() && this.messageBoxContainer) {
if (this.hasNoProblems() && this.messageBoxContainer) {
this.messageBoxContainer.focus();
} else if (this.tree) {
this.tree.getHTMLElement().focus();
......@@ -525,7 +529,7 @@ export class MarkersView extends ViewPane implements IMarkerFilterController {
}
}
private isEmpty(): boolean {
private hasNoProblems(): boolean {
const { total, filtered } = this.getFilterStats();
return total === 0 || filtered === 0;
}
......@@ -534,7 +538,7 @@ export class MarkersView extends ViewPane implements IMarkerFilterController {
this.cachedFilterStats = undefined;
this.resetTree();
if (this.tree) {
this.tree.toggleVisibility(this.isEmpty());
this.tree.toggleVisibility(this.hasNoProblems());
}
this.renderMessage();
}
......
......@@ -48,6 +48,7 @@ import { IDataSource } from 'vs/base/browser/ui/tree/tree';
import { IMarkerDecorationsService } from 'vs/editor/common/services/markersDecorationService';
import { MarkerSeverity } from 'vs/platform/markers/common/markers';
import { IViewDescriptorService } from 'vs/workbench/common/views';
import { IOpenerService } from 'vs/platform/opener/common/opener';
class RequestState {
......@@ -266,8 +267,10 @@ export class OutlinePane extends ViewPane {
@IKeybindingService keybindingService: IKeybindingService,
@IContextKeyService contextKeyService: IContextKeyService,
@IContextMenuService contextMenuService: IContextMenuService,
@IOpenerService openerService: IOpenerService,
@IThemeService themeService: IThemeService,
) {
super(options, keybindingService, contextMenuService, _configurationService, contextKeyService, viewDescriptorService, _instantiationService);
super(options, keybindingService, contextMenuService, _configurationService, contextKeyService, viewDescriptorService, _instantiationService, openerService, themeService);
this._outlineViewState.restore(this._storageService);
this._contextKeyFocused = OutlineViewFocused.bindTo(contextKeyService);
this._contextKeyFiltered = OutlineViewFiltered.bindTo(contextKeyService);
......@@ -295,6 +298,8 @@ export class OutlinePane extends ViewPane {
}
protected renderBody(container: HTMLElement): void {
super.renderBody(container);
this._domNode = container;
this._domNode.tabIndex = 0;
dom.addClass(container, 'outline-pane');
......
......@@ -29,6 +29,7 @@ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { IViewDescriptorService } from 'vs/workbench/common/views';
import { ResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorInput';
import { IOpenerService } from 'vs/platform/opener/common/opener';
export class OutputViewPane extends ViewPane {
......@@ -46,8 +47,10 @@ export class OutputViewPane extends ViewPane {
@IViewDescriptorService viewDescriptorService: IViewDescriptorService,
@IInstantiationService instantiationService: IInstantiationService,
@IOutputService private readonly outputService: IOutputService,
@IOpenerService openerService: IOpenerService,
@IThemeService themeService: IThemeService,
) {
super(options, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService);
super(options, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService);
this.editor = instantiationService.createInstance(OutputEditor);
this._register(this.editor.onTitleAreaUpdate(() => {
this.updateTitle(this.editor.getTitle());
......
......@@ -368,16 +368,19 @@ class HelpPanel extends ViewPane {
@IConfigurationService protected configurationService: IConfigurationService,
@IInstantiationService protected readonly instantiationService: IInstantiationService,
@IViewDescriptorService viewDescriptorService: IViewDescriptorService,
@IOpenerService protected openerService: IOpenerService,
@IOpenerService openerService: IOpenerService,
@IQuickInputService protected quickInputService: IQuickInputService,
@ICommandService protected commandService: ICommandService,
@IRemoteExplorerService protected readonly remoteExplorerService: IRemoteExplorerService,
@IWorkbenchEnvironmentService protected readonly workbenchEnvironmentService: IWorkbenchEnvironmentService
@IWorkbenchEnvironmentService protected readonly workbenchEnvironmentService: IWorkbenchEnvironmentService,
@IThemeService themeService: IThemeService,
) {
super(options, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService);
super(options, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService);
}
protected renderBody(container: HTMLElement): void {
super.renderBody(container);
dom.addClass(container, 'remote-help');
const treeContainer = document.createElement('div');
dom.addClass(treeContainer, 'remote-help-content');
......
......@@ -448,16 +448,16 @@ export class TunnelPanel extends ViewPane {
@IConfigurationService protected configurationService: IConfigurationService,
@IInstantiationService protected readonly instantiationService: IInstantiationService,
@IViewDescriptorService viewDescriptorService: IViewDescriptorService,
@IOpenerService protected openerService: IOpenerService,
@IOpenerService openerService: IOpenerService,
@IQuickInputService protected quickInputService: IQuickInputService,
@ICommandService protected commandService: ICommandService,
@IMenuService private readonly menuService: IMenuService,
@INotificationService private readonly notificationService: INotificationService,
@IContextViewService private readonly contextViewService: IContextViewService,
@IThemeService private readonly themeService: IThemeService,
@IThemeService themeService: IThemeService,
@IRemoteExplorerService private readonly remoteExplorerService: IRemoteExplorerService
) {
super(options, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService);
super(options, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService);
this.tunnelTypeContext = TunnelTypeContextKey.bindTo(contextKeyService);
this.tunnelCloseableContext = TunnelCloseableContextKey.bindTo(contextKeyService);
this.tunnelViewFocusContext = TunnelViewFocusContextKey.bindTo(contextKeyService);
......@@ -484,6 +484,8 @@ export class TunnelPanel extends ViewPane {
}
protected renderBody(container: HTMLElement): void {
super.renderBody(container);
const panelContainer = dom.append(container, dom.$('.tree-explorer-viewlet-tree-view'));
const treeContainer = dom.append(panelContainer, dom.$('.customview-tree'));
dom.addClass(treeContainer, 'file-icon-themable-tree');
......
......@@ -32,6 +32,7 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur
import { IViewDescriptor, IViewDescriptorService } from 'vs/workbench/common/views';
import { SIDE_BAR_BACKGROUND } from 'vs/workbench/common/theme';
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
import { IOpenerService } from 'vs/platform/opener/common/opener';
export interface ISpliceEvent<T> {
index: number;
......@@ -186,12 +187,16 @@ export class MainPane extends ViewPane {
@IViewDescriptorService viewDescriptorService: IViewDescriptorService,
@IContextKeyService private readonly contextKeyService: IContextKeyService,
@IMenuService private readonly menuService: IMenuService,
@IConfigurationService configurationService: IConfigurationService
@IConfigurationService configurationService: IConfigurationService,
@IOpenerService openerService: IOpenerService,
@IThemeService themeService: IThemeService,
) {
super(options, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService);
super(options, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService);
}
protected renderBody(container: HTMLElement): void {
super.renderBody(container);
const delegate = new ProvidersListDelegate();
const renderer = this.instantiationService.createInstance(ProviderRenderer);
const identityProvider = { getId: (r: ISCMRepository) => r.provider.id };
......
......@@ -67,6 +67,7 @@ import { SuggestController } from 'vs/editor/contrib/suggest/suggestController';
import { SnippetController2 } from 'vs/editor/contrib/snippet/snippetController2';
import { Schemas } from 'vs/base/common/network';
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
import { IOpenerService } from 'vs/platform/opener/common/opener';
type TreeElement = ISCMResourceGroup | IResourceNode<ISCMResource, ISCMResourceGroup> | ISCMResource;
......@@ -614,6 +615,8 @@ export class RepositoryPane extends ViewPane {
protected contextKeyService: IContextKeyService;
private commitTemplate = '';
isEmpty() { return true; }
constructor(
readonly repository: ISCMRepository,
options: IViewPaneOptions,
......@@ -631,8 +634,9 @@ export class RepositoryPane extends ViewPane {
@IMenuService protected menuService: IMenuService,
@IStorageService private storageService: IStorageService,
@IModelService private modelService: IModelService,
@IOpenerService openerService: IOpenerService,
) {
super(options, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService);
super(options, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService);
this.menus = instantiationService.createInstance(SCMMenus, this.repository.provider);
this._register(this.menus);
......@@ -665,6 +669,8 @@ export class RepositoryPane extends ViewPane {
}
protected renderBody(container: HTMLElement): void {
super.renderBody(container);
const focusTracker = trackFocus(container);
this._register(focusTracker.onDidFocus(() => this.repository.focus()));
this._register(focusTracker);
......
......@@ -162,16 +162,17 @@ export class SearchView extends ViewPane {
@IReplaceService private readonly replaceService: IReplaceService,
@ITextFileService private readonly textFileService: ITextFileService,
@IPreferencesService private readonly preferencesService: IPreferencesService,
@IThemeService protected themeService: IThemeService,
@IThemeService themeService: IThemeService,
@ISearchHistoryService private readonly searchHistoryService: ISearchHistoryService,
@IContextMenuService contextMenuService: IContextMenuService,
@IMenuService private readonly menuService: IMenuService,
@IAccessibilityService private readonly accessibilityService: IAccessibilityService,
@IKeybindingService keybindingService: IKeybindingService,
@IStorageService storageService: IStorageService,
@IOpenerService private readonly openerService: IOpenerService) {
@IOpenerService openerService: IOpenerService,
) {
super({ ...options, id: VIEW_ID, ariaHeaderLabel: nls.localize('searchView', "Search") }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService);
super({ ...options, id: VIEW_ID, ariaHeaderLabel: nls.localize('searchView', "Search") }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService);
this.container = dom.$('.search-view');
......@@ -254,6 +255,7 @@ export class SearchView extends ViewPane {
}
renderBody(parent: HTMLElement): void {
super.renderBody(parent);
this.container = dom.append(parent, dom.$('.search-view'));
this.searchWidgetsContainerElement = dom.append(this.container, $('.search-widgets-container'));
......
......@@ -28,6 +28,7 @@ import { ViewPane, IViewPaneOptions } from 'vs/workbench/browser/parts/views/vie
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IViewDescriptorService } from 'vs/workbench/common/views';
import { IOpenerService } from 'vs/platform/opener/common/opener';
const FIND_FOCUS_CLASS = 'find-focused';
......@@ -53,9 +54,10 @@ export class TerminalViewPane extends ViewPane {
@IThemeService protected readonly themeService: IThemeService,
@ITelemetryService telemetryService: ITelemetryService,
@INotificationService private readonly _notificationService: INotificationService,
@IStorageService storageService: IStorageService
@IStorageService storageService: IStorageService,
@IOpenerService openerService: IOpenerService,
) {
super(options, keybindingService, _contextMenuService, configurationService, contextKeyService, viewDescriptorService, _instantiationService);
super(options, keybindingService, _contextMenuService, configurationService, contextKeyService, viewDescriptorService, _instantiationService, openerService, themeService);
}
protected renderBody(container: HTMLElement): void {
......
......@@ -30,6 +30,7 @@ import { basename } from 'vs/base/common/path';
import { IProgressService } from 'vs/platform/progress/common/progress';
import { VIEWLET_ID } from 'vs/workbench/contrib/files/common/files';
import { debounce } from 'vs/base/common/decorators';
import { IOpenerService } from 'vs/platform/opener/common/opener';
type TreeElement = TimelineItem;
......@@ -62,9 +63,11 @@ export class TimelinePane extends ViewPane {
@IEditorService protected editorService: IEditorService,
@ICommandService protected commandService: ICommandService,
@IProgressService private readonly progressService: IProgressService,
@ITimelineService protected timelineService: ITimelineService
@ITimelineService protected timelineService: ITimelineService,
@IOpenerService openerService: IOpenerService,
@IThemeService themeService: IThemeService,
) {
super(options, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService);
super(options, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService);
const scopedContextKeyService = this._register(this.contextKeyService.createScoped());
scopedContextKeyService.createKey('view', TimelinePane.ID);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册