mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 18:46:40 -05:00
Merge from vscode 52dcb723a39ae75bee1bd56b3312d7fcdc87aeed (#6719)
This commit is contained in:
@@ -156,7 +156,7 @@ export interface IActionBarRegistry {
|
||||
class ActionBarRegistry implements IActionBarRegistry {
|
||||
private readonly actionBarContributorConstructors: { scope: string; ctor: IConstructorSignature0<ActionBarContributor>; }[] = [];
|
||||
private readonly actionBarContributorInstances: Map<string, ActionBarContributor[]> = new Map();
|
||||
private instantiationService: IInstantiationService;
|
||||
private instantiationService!: IInstantiationService;
|
||||
|
||||
start(accessor: ServicesAccessor): void {
|
||||
this.instantiationService = accessor.get(IInstantiationService);
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import 'vs/css!./media/screencast';
|
||||
|
||||
import { Action } from 'vs/base/common/actions';
|
||||
import { IWindowService } from 'vs/platform/windows/common/windows';
|
||||
import * as nls from 'vs/nls';
|
||||
@@ -11,6 +13,7 @@ import { domEvent } from 'vs/base/browser/event';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { IDisposable, toDisposable, dispose, Disposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { getDomNodePagePosition, createStyleSheet, createCSSRule, append, $ } from 'vs/base/browser/dom';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { Context } from 'vs/platform/contextkey/browser/contextKeyService';
|
||||
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
@@ -20,6 +23,9 @@ import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { SyncActionDescriptor } from 'vs/platform/actions/common/actions';
|
||||
import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actions';
|
||||
import { IStorageService } from 'vs/platform/storage/common/storage';
|
||||
import { clamp } from 'vs/base/common/numbers';
|
||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { IConfigurationRegistry, Extensions as ConfigurationExtensions } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
|
||||
export class InspectContextKeysAction extends Action {
|
||||
|
||||
@@ -96,7 +102,8 @@ export class ToggleScreencastModeAction extends Action {
|
||||
id: string,
|
||||
label: string,
|
||||
@IKeybindingService private readonly keybindingService: IKeybindingService,
|
||||
@IWorkbenchLayoutService private readonly layoutService: IWorkbenchLayoutService
|
||||
@IWorkbenchLayoutService private readonly layoutService: IWorkbenchLayoutService,
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService
|
||||
) {
|
||||
super(id, label);
|
||||
}
|
||||
@@ -108,26 +115,17 @@ export class ToggleScreencastModeAction extends Action {
|
||||
return;
|
||||
}
|
||||
|
||||
const container = this.layoutService.getWorkbenchElement();
|
||||
const disposables = new DisposableStore();
|
||||
|
||||
const mouseMarker = append(container, $('div'));
|
||||
mouseMarker.style.position = 'absolute';
|
||||
mouseMarker.style.border = '2px solid red';
|
||||
mouseMarker.style.borderRadius = '20px';
|
||||
mouseMarker.style.width = '20px';
|
||||
mouseMarker.style.height = '20px';
|
||||
mouseMarker.style.top = '0';
|
||||
mouseMarker.style.left = '0';
|
||||
mouseMarker.style.zIndex = '100000';
|
||||
mouseMarker.style.content = ' ';
|
||||
mouseMarker.style.pointerEvents = 'none';
|
||||
mouseMarker.style.display = 'none';
|
||||
const container = this.layoutService.getWorkbenchElement();
|
||||
const mouseMarker = append(container, $('.screencast-mouse'));
|
||||
disposables.add(toDisposable(() => mouseMarker.remove()));
|
||||
|
||||
const onMouseDown = domEvent(container, 'mousedown', true);
|
||||
const onMouseUp = domEvent(container, 'mouseup', true);
|
||||
const onMouseMove = domEvent(container, 'mousemove', true);
|
||||
|
||||
const mouseListener = onMouseDown(e => {
|
||||
disposables.add(onMouseDown(e => {
|
||||
mouseMarker.style.top = `${e.clientY - 10}px`;
|
||||
mouseMarker.style.left = `${e.clientX - 10}px`;
|
||||
mouseMarker.style.display = 'block';
|
||||
@@ -141,56 +139,59 @@ export class ToggleScreencastModeAction extends Action {
|
||||
mouseMarker.style.display = 'none';
|
||||
mouseMoveListener.dispose();
|
||||
});
|
||||
});
|
||||
}));
|
||||
|
||||
const keyboardMarker = append(container, $('div'));
|
||||
keyboardMarker.style.position = 'absolute';
|
||||
keyboardMarker.style.backgroundColor = 'rgba(0, 0, 0 ,0.5)';
|
||||
keyboardMarker.style.width = '100%';
|
||||
keyboardMarker.style.height = '100px';
|
||||
keyboardMarker.style.bottom = '20%';
|
||||
keyboardMarker.style.left = '0';
|
||||
keyboardMarker.style.zIndex = '100000';
|
||||
keyboardMarker.style.pointerEvents = 'none';
|
||||
keyboardMarker.style.color = 'white';
|
||||
keyboardMarker.style.lineHeight = '100px';
|
||||
keyboardMarker.style.textAlign = 'center';
|
||||
keyboardMarker.style.fontSize = '56px';
|
||||
keyboardMarker.style.display = 'none';
|
||||
const keyboardMarker = append(container, $('.screencast-keyboard'));
|
||||
disposables.add(toDisposable(() => keyboardMarker.remove()));
|
||||
|
||||
const updateKeyboardMarker = () => {
|
||||
keyboardMarker.style.bottom = `${clamp(this.configurationService.getValue<number>('screencastMode.verticalOffset') || 0, 0, 90)}%`;
|
||||
};
|
||||
|
||||
updateKeyboardMarker();
|
||||
disposables.add(this.configurationService.onDidChangeConfiguration(e => {
|
||||
if (e.affectsConfiguration('screencastMode.verticalOffset')) {
|
||||
updateKeyboardMarker();
|
||||
}
|
||||
}));
|
||||
|
||||
const onKeyDown = domEvent(container, 'keydown', true);
|
||||
let keyboardTimeout: IDisposable = Disposable.None;
|
||||
let length = 0;
|
||||
|
||||
const keyboardListener = onKeyDown(e => {
|
||||
disposables.add(onKeyDown(e => {
|
||||
keyboardTimeout.dispose();
|
||||
|
||||
const event = new StandardKeyboardEvent(e);
|
||||
const keybinding = this.keybindingService.resolveKeyboardEvent(event);
|
||||
const label = keybinding.getLabel();
|
||||
const shortcut = this.keybindingService.softDispatch(event, event.target);
|
||||
|
||||
if (!event.ctrlKey && !event.altKey && !event.metaKey && !event.shiftKey && this.keybindingService.mightProducePrintableCharacter(event) && label) {
|
||||
keyboardMarker.textContent += ' ' + label;
|
||||
} else {
|
||||
keyboardMarker.textContent = label;
|
||||
if (shortcut || !this.configurationService.getValue<boolean>('screencastMode.onlyKeyboardShortcuts')) {
|
||||
if (
|
||||
event.ctrlKey || event.altKey || event.metaKey || event.shiftKey
|
||||
|| length > 20
|
||||
|| event.keyCode === KeyCode.Backspace || event.keyCode === KeyCode.Escape
|
||||
) {
|
||||
keyboardMarker.innerHTML = '';
|
||||
length = 0;
|
||||
}
|
||||
|
||||
const keybinding = this.keybindingService.resolveKeyboardEvent(event);
|
||||
const label = keybinding.getLabel();
|
||||
const key = $('span.key', {}, label || '');
|
||||
length++;
|
||||
append(keyboardMarker, key);
|
||||
}
|
||||
|
||||
keyboardMarker.style.display = 'block';
|
||||
|
||||
const promise = timeout(800);
|
||||
keyboardTimeout = toDisposable(() => promise.cancel());
|
||||
|
||||
promise.then(() => {
|
||||
keyboardMarker.textContent = '';
|
||||
keyboardMarker.style.display = 'none';
|
||||
length = 0;
|
||||
});
|
||||
});
|
||||
}));
|
||||
|
||||
ToggleScreencastModeAction.disposable = toDisposable(() => {
|
||||
mouseListener.dispose();
|
||||
keyboardListener.dispose();
|
||||
mouseMarker.remove();
|
||||
keyboardMarker.remove();
|
||||
});
|
||||
ToggleScreencastModeAction.disposable = disposables;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,8 +216,35 @@ export class LogStorageAction extends Action {
|
||||
}
|
||||
}
|
||||
|
||||
// --- Actions Registration
|
||||
|
||||
const developerCategory = nls.localize('developer', "Developer");
|
||||
const registry = Registry.as<IWorkbenchActionRegistry>(Extensions.WorkbenchActions);
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(InspectContextKeysAction, InspectContextKeysAction.ID, InspectContextKeysAction.LABEL), 'Developer: Inspect Context Keys', developerCategory);
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(ToggleScreencastModeAction, ToggleScreencastModeAction.ID, ToggleScreencastModeAction.LABEL), 'Developer: Toggle Screencast Mode', developerCategory);
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(LogStorageAction, LogStorageAction.ID, LogStorageAction.LABEL), 'Developer: Log Storage Database Contents', developerCategory);
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(LogStorageAction, LogStorageAction.ID, LogStorageAction.LABEL), 'Developer: Log Storage Database Contents', developerCategory);
|
||||
|
||||
// --- Menu Registration
|
||||
|
||||
// Screencast Mode
|
||||
const configurationRegistry = Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration);
|
||||
configurationRegistry.registerConfiguration({
|
||||
id: 'screencastMode',
|
||||
order: 9,
|
||||
title: nls.localize('screencastModeConfigurationTitle', "Screencast Mode"),
|
||||
type: 'object',
|
||||
properties: {
|
||||
'screencastMode.verticalOffset': {
|
||||
type: 'number',
|
||||
default: 20,
|
||||
minimum: 0,
|
||||
maximum: 90,
|
||||
description: nls.localize('screencastMode.location.verticalPosition', "Controls the vertical offset of the screencast mode overlay from the bottom as a percentage of the workbench height.")
|
||||
},
|
||||
'screencastMode.onlyKeyboardShortcuts': {
|
||||
type: 'boolean',
|
||||
description: nls.localize('screencastMode.onlyKeyboardShortcuts', "Only show keyboard shortcuts in Screencast Mode."),
|
||||
default: false
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -320,6 +320,38 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: 'list.focusParent',
|
||||
weight: KeybindingWeight.WorkbenchContrib,
|
||||
when: WorkbenchListFocusContextKey,
|
||||
handler: (accessor) => {
|
||||
const focused = accessor.get(IListService).lastFocusedList;
|
||||
|
||||
if (!focused || focused instanceof List || focused instanceof PagedList) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (focused instanceof ObjectTree || focused instanceof DataTree || focused instanceof AsyncDataTree) {
|
||||
const tree = focused;
|
||||
const focusedElements = tree.getFocus();
|
||||
if (focusedElements.length === 0) {
|
||||
return;
|
||||
}
|
||||
const focus = focusedElements[0];
|
||||
const parent = tree.getParentElement(focus);
|
||||
if (parent) {
|
||||
const fakeKeyboardEvent = new KeyboardEvent('keydown');
|
||||
tree.setFocus([parent], fakeKeyboardEvent);
|
||||
tree.reveal(parent);
|
||||
}
|
||||
} else {
|
||||
const tree = focused;
|
||||
tree.focusParent({ origin: 'keyboard' });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: 'list.expand',
|
||||
weight: KeybindingWeight.WorkbenchContrib,
|
||||
@@ -749,11 +781,8 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
if (focused instanceof List || focused instanceof PagedList) {
|
||||
const list = focused;
|
||||
|
||||
if (list.getSelection().length > 0) {
|
||||
list.setSelection([]);
|
||||
} else if (list.getFocus().length > 0) {
|
||||
list.setFocus([]);
|
||||
}
|
||||
list.setSelection([]);
|
||||
list.setFocus([]);
|
||||
}
|
||||
|
||||
// ObjectTree
|
||||
@@ -761,22 +790,16 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
const list = focused;
|
||||
const fakeKeyboardEvent = new KeyboardEvent('keydown');
|
||||
|
||||
if (list.getSelection().length > 0) {
|
||||
list.setSelection([], fakeKeyboardEvent);
|
||||
} else if (list.getFocus().length > 0) {
|
||||
list.setFocus([], fakeKeyboardEvent);
|
||||
}
|
||||
list.setSelection([], fakeKeyboardEvent);
|
||||
list.setFocus([], fakeKeyboardEvent);
|
||||
}
|
||||
|
||||
// Tree
|
||||
else if (focused) {
|
||||
const tree = focused;
|
||||
|
||||
if (tree.getSelection().length) {
|
||||
tree.clearSelection({ origin: 'keyboard' });
|
||||
} else if (tree.getFocus()) {
|
||||
tree.clearFocus({ origin: 'keyboard' });
|
||||
}
|
||||
tree.clearSelection({ origin: 'keyboard' });
|
||||
tree.clearFocus({ origin: 'keyboard' });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
50
src/vs/workbench/browser/actions/media/screencast.css
Normal file
50
src/vs/workbench/browser/actions/media/screencast.css
Normal file
@@ -0,0 +1,50 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
.monaco-workbench .screencast-mouse {
|
||||
position: absolute;
|
||||
border: 2px solid red;
|
||||
border-radius: 20px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 100000;
|
||||
content: ' ';
|
||||
pointer-events: none;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.monaco-workbench .screencast-keyboard {
|
||||
position: absolute;
|
||||
background-color: rgba(0, 0, 0 ,0.5);
|
||||
width: 100%;
|
||||
height: 100px;
|
||||
bottom: 20%;
|
||||
left: 0;
|
||||
z-index: 100000;
|
||||
pointer-events: none;
|
||||
color: #eee;
|
||||
line-height: 100px;
|
||||
text-align: center;
|
||||
font-size: 56px;
|
||||
transition: opacity 0.3s ease-out;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.monaco-workbench .screencast-keyboard:empty {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.monaco-workbench .screencast-keyboard > .key {
|
||||
padding: 0 8px;
|
||||
box-shadow: inset 0 -3px 0 hsla(0,0%,73%,.4);
|
||||
margin-right: 6px;
|
||||
border: 1px solid hsla(0,0%,80%,.4);
|
||||
border-radius: 5px;
|
||||
background-color: rgba(255, 255, 255, 0.05);
|
||||
}
|
||||
@@ -7,11 +7,11 @@ import 'vs/css!./media/actions';
|
||||
|
||||
import * as nls from 'vs/nls';
|
||||
import { Action } from 'vs/base/common/actions';
|
||||
import { IWindowService, IURIToOpen } from 'vs/platform/windows/common/windows';
|
||||
import { IWindowService, IURIToOpen, IWindowsService } from 'vs/platform/windows/common/windows';
|
||||
import { SyncActionDescriptor, MenuRegistry, MenuId } from 'vs/platform/actions/common/actions';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
|
||||
import { IsFullscreenContext, IsDevelopmentContext } from 'vs/workbench/browser/contextkeys';
|
||||
import { IsFullscreenContext, IsDevelopmentContext, IsMacNativeContext } from 'vs/workbench/browser/contextkeys';
|
||||
import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actions';
|
||||
import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
|
||||
import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
@@ -226,6 +226,24 @@ export class ReloadWindowAction extends Action {
|
||||
}
|
||||
}
|
||||
|
||||
export class ShowAboutDialogAction extends Action {
|
||||
|
||||
static readonly ID = 'workbench.action.showAboutDialog';
|
||||
static readonly LABEL = nls.localize('about', "About");
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
@IWindowsService private readonly windowsService: IWindowsService
|
||||
) {
|
||||
super(id, label);
|
||||
}
|
||||
|
||||
run(): Promise<void> {
|
||||
return this.windowsService.openAboutDialog();
|
||||
}
|
||||
}
|
||||
|
||||
const registry = Registry.as<IWorkbenchActionRegistry>(Extensions.WorkbenchActions);
|
||||
|
||||
// --- Actions Registration
|
||||
@@ -240,6 +258,9 @@ registry.registerWorkbenchAction(new SyncActionDescriptor(ToggleFullScreenAction
|
||||
const developerCategory = nls.localize('developer', "Developer");
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(ReloadWindowAction, ReloadWindowAction.ID, ReloadWindowAction.LABEL), 'Developer: Reload Window', developerCategory);
|
||||
|
||||
const helpCategory = nls.localize('help', "Help");
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(ShowAboutDialogAction, ShowAboutDialogAction.ID, ShowAboutDialogAction.LABEL), `Help: About`, helpCategory);
|
||||
|
||||
// --- Commands/Keybindings Registration
|
||||
|
||||
const recentFilesPickerContext = ContextKeyExpr.and(inQuickOpenContext, ContextKeyExpr.has(inRecentFilesPickerContextKey));
|
||||
@@ -297,4 +318,14 @@ MenuRegistry.appendMenuItem(MenuId.MenubarAppearanceMenu, {
|
||||
toggled: IsFullscreenContext
|
||||
},
|
||||
order: 1
|
||||
});
|
||||
});
|
||||
|
||||
MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, {
|
||||
group: 'z_about',
|
||||
command: {
|
||||
id: ShowAboutDialogAction.ID,
|
||||
title: nls.localize({ key: 'miAbout', comment: ['&& denotes a mnemonic'] }, "&&About")
|
||||
},
|
||||
order: 1,
|
||||
when: IsMacNativeContext.toNegated()
|
||||
});
|
||||
|
||||
@@ -11,7 +11,7 @@ import { IWorkspaceContextService, WorkbenchState, IWorkspaceFolder } from 'vs/p
|
||||
import { IWorkspaceEditingService } from 'vs/workbench/services/workspace/common/workspaceEditing';
|
||||
import { IWorkspacesService } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { ICommandService, ICommandHandler } from 'vs/platform/commands/common/commands';
|
||||
import { ICommandService, ICommandHandler, CommandsRegistry } from 'vs/platform/commands/common/commands';
|
||||
import { ADD_ROOT_FOLDER_COMMAND_ID, ADD_ROOT_FOLDER_LABEL, PICK_WORKSPACE_FOLDER_COMMAND_ID } from 'vs/workbench/browser/actions/workspaceCommands';
|
||||
import { IFileDialogService } from 'vs/platform/dialogs/common/dialogs';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
@@ -20,6 +20,9 @@ import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/
|
||||
import { ITextFileService, ISaveOptions } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
import { toResource } from 'vs/workbench/common/editor';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { MenuRegistry, MenuId } from 'vs/platform/actions/common/actions';
|
||||
import { WorkbenchStateContext } from 'vs/workbench/browser/contextkeys';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
|
||||
export class OpenFileAction extends Action {
|
||||
|
||||
@@ -305,3 +308,19 @@ export class DuplicateWorkspaceInNewWindowAction extends Action {
|
||||
return this.windowService.openWindow([{ workspaceUri: newWorkspace.configPath }], { forceNewWindow: true });
|
||||
}
|
||||
}
|
||||
|
||||
// --- Menu Registration
|
||||
|
||||
const workspacesCategory = nls.localize('workspaces', "Workspaces");
|
||||
|
||||
CommandsRegistry.registerCommand(OpenWorkspaceConfigFileAction.ID, serviceAccessor => {
|
||||
serviceAccessor.get(IInstantiationService).createInstance(OpenWorkspaceConfigFileAction, OpenWorkspaceConfigFileAction.ID, OpenWorkspaceConfigFileAction.LABEL).run();
|
||||
});
|
||||
|
||||
MenuRegistry.appendMenuItem(MenuId.CommandPalette, {
|
||||
command: {
|
||||
id: OpenWorkspaceConfigFileAction.ID,
|
||||
title: { value: `${workspacesCategory}: ${OpenWorkspaceConfigFileAction.LABEL}`, original: 'Workspaces: Open Workspace Configuration File' },
|
||||
},
|
||||
when: WorkbenchStateContext.isEqualTo('workspace')
|
||||
});
|
||||
|
||||
@@ -35,7 +35,7 @@ export abstract class Composite extends Component implements IComposite {
|
||||
private readonly _onDidChangeVisibility: Emitter<boolean> = this._register(new Emitter<boolean>());
|
||||
readonly onDidChangeVisibility: Event<boolean> = this._onDidChangeVisibility.event;
|
||||
|
||||
private _onDidFocus: Emitter<void>;
|
||||
private _onDidFocus!: Emitter<void>;
|
||||
get onDidFocus(): Event<void> {
|
||||
if (!this._onDidFocus) {
|
||||
this.registerFocusTrackEvents();
|
||||
@@ -50,7 +50,7 @@ export abstract class Composite extends Component implements IComposite {
|
||||
}
|
||||
}
|
||||
|
||||
private _onDidBlur: Emitter<void>;
|
||||
private _onDidBlur!: Emitter<void>;
|
||||
get onDidBlur(): Event<void> {
|
||||
if (!this._onDidBlur) {
|
||||
this.registerFocusTrackEvents();
|
||||
@@ -68,10 +68,10 @@ export abstract class Composite extends Component implements IComposite {
|
||||
this._register(focusTracker.onDidBlur(() => this._onDidBlur.fire()));
|
||||
}
|
||||
|
||||
protected actionRunner: IActionRunner;
|
||||
protected actionRunner: IActionRunner | undefined;
|
||||
|
||||
private visible: boolean;
|
||||
private parent: HTMLElement;
|
||||
private parent!: HTMLElement;
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
|
||||
@@ -8,7 +8,7 @@ import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { IContextKeyService, IContextKey, RawContextKey } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { InputFocusedContext } from 'vs/platform/contextkey/common/contextkeys';
|
||||
import { IWindowsConfiguration } from 'vs/platform/windows/common/windows';
|
||||
import { ActiveEditorContext, EditorsVisibleContext, TextCompareEditorVisibleContext, TextCompareEditorActiveContext, ActiveEditorGroupEmptyContext, MultipleEditorGroupsContext, TEXT_DIFF_EDITOR_ID, SplitEditorsVertically, InEditorZenModeContext, IsCenteredLayoutContext } from 'vs/workbench/common/editor';
|
||||
import { ActiveEditorContext, EditorsVisibleContext, TextCompareEditorVisibleContext, TextCompareEditorActiveContext, ActiveEditorGroupEmptyContext, MultipleEditorGroupsContext, TEXT_DIFF_EDITOR_ID, SplitEditorsVertically, InEditorZenModeContext, IsCenteredLayoutContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext } from 'vs/workbench/common/editor';
|
||||
import { trackFocus, addDisposableListener, EventType } from 'vs/base/browser/dom';
|
||||
import { preferredSideBySideGroupDirection, GroupDirection, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
@@ -52,17 +52,20 @@ export class WorkbenchContextKeysHandler extends Disposable {
|
||||
private inputFocusedContext: IContextKey<boolean>;
|
||||
|
||||
private activeEditorContext: IContextKey<string | null>;
|
||||
|
||||
private activeEditorGroupEmpty: IContextKey<boolean>;
|
||||
private activeEditorGroupIndex: IContextKey<number>;
|
||||
private activeEditorGroupLast: IContextKey<boolean>;
|
||||
private multipleEditorGroupsContext: IContextKey<boolean>;
|
||||
|
||||
private editorsVisibleContext: IContextKey<boolean>;
|
||||
private textCompareEditorVisibleContext: IContextKey<boolean>;
|
||||
private textCompareEditorActiveContext: IContextKey<boolean>;
|
||||
private activeEditorGroupEmpty: IContextKey<boolean>;
|
||||
private multipleEditorGroupsContext: IContextKey<boolean>;
|
||||
private splitEditorsVerticallyContext: IContextKey<boolean>;
|
||||
|
||||
private workbenchStateContext: IContextKey<string>;
|
||||
private workspaceFolderCountContext: IContextKey<number>;
|
||||
|
||||
|
||||
private inZenModeContext: IContextKey<boolean>;
|
||||
private isFullscreenContext: IContextKey<boolean>;
|
||||
private isCenteredLayoutContext: IContextKey<boolean>;
|
||||
@@ -90,8 +93,10 @@ export class WorkbenchContextKeysHandler extends Disposable {
|
||||
|
||||
this._register(this.editorService.onDidActiveEditorChange(() => this.updateEditorContextKeys()));
|
||||
this._register(this.editorService.onDidVisibleEditorsChange(() => this.updateEditorContextKeys()));
|
||||
|
||||
this._register(this.editorGroupService.onDidAddGroup(() => this.updateEditorContextKeys()));
|
||||
this._register(this.editorGroupService.onDidRemoveGroup(() => this.updateEditorContextKeys()));
|
||||
this._register(this.editorGroupService.onDidGroupIndexChange(() => this.updateEditorContextKeys()));
|
||||
|
||||
this._register(addDisposableListener(window, EventType.FOCUS_IN, () => this.updateInputContextKeys(), true));
|
||||
|
||||
@@ -141,6 +146,8 @@ export class WorkbenchContextKeysHandler extends Disposable {
|
||||
this.textCompareEditorVisibleContext = TextCompareEditorVisibleContext.bindTo(this.contextKeyService);
|
||||
this.textCompareEditorActiveContext = TextCompareEditorActiveContext.bindTo(this.contextKeyService);
|
||||
this.activeEditorGroupEmpty = ActiveEditorGroupEmptyContext.bindTo(this.contextKeyService);
|
||||
this.activeEditorGroupIndex = ActiveEditorGroupIndexContext.bindTo(this.contextKeyService);
|
||||
this.activeEditorGroupLast = ActiveEditorGroupLastContext.bindTo(this.contextKeyService);
|
||||
this.multipleEditorGroupsContext = MultipleEditorGroupsContext.bindTo(this.contextKeyService);
|
||||
|
||||
// Inputs
|
||||
@@ -176,6 +183,7 @@ export class WorkbenchContextKeysHandler extends Disposable {
|
||||
}
|
||||
|
||||
private updateEditorContextKeys(): void {
|
||||
const activeGroup = this.editorGroupService.activeGroup;
|
||||
const activeControl = this.editorService.activeControl;
|
||||
const visibleEditors = this.editorService.visibleControls;
|
||||
|
||||
@@ -194,12 +202,16 @@ export class WorkbenchContextKeysHandler extends Disposable {
|
||||
this.activeEditorGroupEmpty.reset();
|
||||
}
|
||||
|
||||
if (this.editorGroupService.count > 1) {
|
||||
const groupCount = this.editorGroupService.count;
|
||||
if (groupCount > 1) {
|
||||
this.multipleEditorGroupsContext.set(true);
|
||||
} else {
|
||||
this.multipleEditorGroupsContext.reset();
|
||||
}
|
||||
|
||||
this.activeEditorGroupIndex.set(activeGroup.index);
|
||||
this.activeEditorGroupLast.set(activeGroup.index === groupCount - 1);
|
||||
|
||||
if (activeControl) {
|
||||
this.activeEditorContext.set(activeControl.getId());
|
||||
} else {
|
||||
|
||||
@@ -27,13 +27,15 @@ import { IWindowService, MenuBarVisibility, getTitleBarStyle } from 'vs/platform
|
||||
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
||||
import { IEditorService, IResourceEditor } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { Sizing, Direction, Grid, SerializableGrid, ISerializableView, ISerializedGrid, GridBranchNode, GridLeafNode, isGridBranchNode } from 'vs/base/browser/ui/grid/grid';
|
||||
import { Grid, SerializableGrid, ISerializableView, ISerializedGrid, Orientation, ISerializedNode, ISerializedLeafNode, Direction } from 'vs/base/browser/ui/grid/grid';
|
||||
import { WorkbenchLegacyLayout } from 'vs/workbench/browser/legacyLayout';
|
||||
import { IDimension } from 'vs/platform/layout/browser/layoutService';
|
||||
import { Part } from 'vs/workbench/browser/part';
|
||||
import { IStatusbarService } from 'vs/platform/statusbar/common/statusbar';
|
||||
import { IActivityBarService } from 'vs/workbench/services/activityBar/browser/activityBarService';
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { isCodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { coalesce } from 'vs/base/common/arrays';
|
||||
|
||||
enum Settings {
|
||||
MENUBAR_VISIBLE = 'window.menuBarVisibility',
|
||||
@@ -44,25 +46,36 @@ enum Settings {
|
||||
PANEL_POSITION = 'workbench.panel.defaultLocation',
|
||||
|
||||
ZEN_MODE_RESTORE = 'zenMode.restore',
|
||||
|
||||
}
|
||||
|
||||
enum Storage {
|
||||
SIDEBAR_HIDDEN = 'workbench.sidebar.hidden',
|
||||
SIDEBAR_SIZE = 'workbench.sidebar.size',
|
||||
|
||||
PANEL_HIDDEN = 'workbench.panel.hidden',
|
||||
PANEL_POSITION = 'workbench.panel.location',
|
||||
PANEL_SIZE = 'workbench.panel.size',
|
||||
PANEL_SIZE_BEFORE_MAXIMIZED = 'workbench.panel.sizeBeforeMaximized',
|
||||
|
||||
ZEN_MODE_ENABLED = 'workbench.zenmode.active',
|
||||
CENTERED_LAYOUT_ENABLED = 'workbench.centerededitorlayout.active',
|
||||
|
||||
GRID_LAYOUT = 'workbench.grid.layout'
|
||||
GRID_LAYOUT = 'workbench.grid.layout',
|
||||
GRID_WIDTH = 'workbench.grid.width',
|
||||
GRID_HEIGHT = 'workbench.grid.height'
|
||||
}
|
||||
|
||||
enum Classes {
|
||||
SIDEBAR_HIDDEN = 'nosidebar',
|
||||
EDITOR_HIDDEN = 'noeditorarea',
|
||||
PANEL_HIDDEN = 'nopanel',
|
||||
STATUSBAR_HIDDEN = 'nostatusbar',
|
||||
FULLSCREEN = 'fullscreen'
|
||||
}
|
||||
|
||||
export abstract class Layout extends Disposable implements IWorkbenchLayoutService {
|
||||
|
||||
_serviceBrand: ServiceIdentifier<any>;
|
||||
_serviceBrand!: ServiceIdentifier<any>;
|
||||
|
||||
private readonly _onTitleBarVisibilityChange: Emitter<void> = this._register(new Emitter<void>());
|
||||
readonly onTitleBarVisibilityChange: Event<void> = this._onTitleBarVisibilityChange.event;
|
||||
@@ -232,6 +245,11 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
|
||||
if (this.state.fullscreen && (this.state.menuBar.visibility === 'toggle' || this.state.menuBar.visibility === 'default')) {
|
||||
this._onTitleBarVisibilityChange.fire();
|
||||
|
||||
if (this.workbenchGrid instanceof SerializableGrid) {
|
||||
this.workbenchGrid.setViewVisible(this.titleBarPartView, this.isVisible(Parts.TITLEBAR_PART));
|
||||
}
|
||||
|
||||
this.layout();
|
||||
}
|
||||
}
|
||||
@@ -242,9 +260,9 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
|
||||
// Apply as CSS class
|
||||
if (this.state.fullscreen) {
|
||||
addClass(this.container, 'fullscreen');
|
||||
addClass(this.container, Classes.FULLSCREEN);
|
||||
} else {
|
||||
removeClass(this.container, 'fullscreen');
|
||||
removeClass(this.container, Classes.FULLSCREEN);
|
||||
|
||||
if (this.state.zenMode.transitionedToFullScreen && this.state.zenMode.active) {
|
||||
this.toggleZenMode();
|
||||
@@ -254,6 +272,11 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
// Changing fullscreen state of the window has an impact on custom title bar visibility, so we need to update
|
||||
if (getTitleBarStyle(this.configurationService, this.environmentService) === 'custom') {
|
||||
this._onTitleBarVisibilityChange.fire();
|
||||
|
||||
if (this.workbenchGrid instanceof SerializableGrid) {
|
||||
this.workbenchGrid.setViewVisible(this.titleBarPartView, this.isVisible(Parts.TITLEBAR_PART));
|
||||
}
|
||||
|
||||
this.layout(); // handle title bar when fullscreen changes
|
||||
}
|
||||
|
||||
@@ -297,11 +320,6 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
const activityBar = this.getPart(Parts.ACTIVITYBAR_PART);
|
||||
const sideBar = this.getPart(Parts.SIDEBAR_PART);
|
||||
const wasHidden = this.state.sideBar.hidden;
|
||||
|
||||
if (this.state.sideBar.hidden) {
|
||||
this.setSideBarHidden(false, true /* Skip Layout */);
|
||||
}
|
||||
|
||||
const newPositionValue = (position === Position.LEFT) ? 'left' : 'right';
|
||||
const oldPositionValue = (this.state.sideBar.position === Position.LEFT) ? 'left' : 'right';
|
||||
this.state.sideBar.position = position;
|
||||
@@ -322,11 +340,12 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
this.state.sideBar.width = this.workbenchGrid.getViewSize(this.sideBarPartView).width;
|
||||
}
|
||||
|
||||
this.workbenchGrid.removeView(this.sideBarPartView);
|
||||
this.workbenchGrid.removeView(this.activityBarPartView);
|
||||
|
||||
if (!this.state.panel.hidden && this.state.panel.position === Position.BOTTOM) {
|
||||
this.workbenchGrid.removeView(this.panelPartView);
|
||||
if (position === Position.LEFT) {
|
||||
this.workbenchGrid.moveViewTo(this.activityBarPartView, [1, 0]);
|
||||
this.workbenchGrid.moveViewTo(this.sideBarPartView, [1, 1]);
|
||||
} else {
|
||||
this.workbenchGrid.moveViewTo(this.sideBarPartView, [1, 4]);
|
||||
this.workbenchGrid.moveViewTo(this.activityBarPartView, [1, 4]);
|
||||
}
|
||||
|
||||
this.layout();
|
||||
@@ -578,7 +597,15 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
this.state.zenMode.active = !this.state.zenMode.active;
|
||||
this.state.zenMode.transitionDisposables.clear();
|
||||
|
||||
const setLineNumbers = (lineNumbers: any) => this.editorService.visibleTextEditorWidgets.forEach(editor => editor.updateOptions({ lineNumbers }));
|
||||
const setLineNumbers = (lineNumbers?: any) => this.editorService.visibleTextEditorWidgets.forEach(editor => {
|
||||
// To properly reset line numbers we need to read the configuration for each editor respecting it's uri.
|
||||
if (!lineNumbers && isCodeEditor(editor) && editor.hasModel()) {
|
||||
const model = editor.getModel();
|
||||
this.configurationService.getValue('editor.lineNumbers', { resource: model.uri });
|
||||
} else {
|
||||
editor.updateOptions({ lineNumbers });
|
||||
}
|
||||
});
|
||||
|
||||
// Check if zen mode transitioned to full screen and if now we are out of zen mode
|
||||
// -> we need to go out of full screen (same goes for the centered editor layout)
|
||||
@@ -641,7 +668,7 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
this.centerEditorLayout(false, true);
|
||||
}
|
||||
|
||||
setLineNumbers(this.configurationService.getValue('editor.lineNumbers'));
|
||||
setLineNumbers();
|
||||
|
||||
// Status bar and activity bar visibility come from settings -> update their visibility.
|
||||
this.doUpdateLayoutConfiguration(true);
|
||||
@@ -684,16 +711,19 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
|
||||
// Adjust CSS
|
||||
if (hidden) {
|
||||
addClass(this.container, 'nostatusbar');
|
||||
addClass(this.container, Classes.STATUSBAR_HIDDEN);
|
||||
} else {
|
||||
removeClass(this.container, 'nostatusbar');
|
||||
removeClass(this.container, Classes.STATUSBAR_HIDDEN);
|
||||
}
|
||||
|
||||
// Propagate to grid
|
||||
if (this.workbenchGrid instanceof Grid) {
|
||||
this.workbenchGrid.setViewVisible(this.statusBarPartView, !hidden);
|
||||
}
|
||||
|
||||
// Layout
|
||||
if (!skipLayout) {
|
||||
if (this.workbenchGrid instanceof Grid) {
|
||||
this.layout();
|
||||
} else {
|
||||
if (!(this.workbenchGrid instanceof Grid)) {
|
||||
this.workbenchGrid.layout();
|
||||
}
|
||||
}
|
||||
@@ -717,64 +747,21 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
this.panelPartView = panelPart;
|
||||
this.statusBarPartView = statusBar;
|
||||
|
||||
let workbenchGrid: SerializableGrid<ISerializableView> | undefined;
|
||||
const viewMap = {
|
||||
[Parts.ACTIVITYBAR_PART]: this.activityBarPartView,
|
||||
[Parts.TITLEBAR_PART]: this.titleBarPartView,
|
||||
[Parts.EDITOR_PART]: this.editorPartView,
|
||||
[Parts.PANEL_PART]: this.panelPartView,
|
||||
[Parts.SIDEBAR_PART]: this.sideBarPartView,
|
||||
[Parts.STATUSBAR_PART]: this.statusBarPartView
|
||||
};
|
||||
|
||||
const savedGrid = this.storageService.get(Storage.GRID_LAYOUT, StorageScope.GLOBAL, undefined);
|
||||
if (savedGrid) {
|
||||
const parsedGrid: ISerializedGrid = JSON.parse(savedGrid);
|
||||
|
||||
const fromJSON = (serializedPart: { type: Parts } | null) => {
|
||||
if (serializedPart && serializedPart.type) {
|
||||
switch (serializedPart.type) {
|
||||
case Parts.ACTIVITYBAR_PART:
|
||||
return this.activityBarPartView;
|
||||
case Parts.TITLEBAR_PART:
|
||||
return this.titleBarPartView;
|
||||
case Parts.EDITOR_PART:
|
||||
return this.editorPartView;
|
||||
case Parts.PANEL_PART:
|
||||
return this.panelPartView;
|
||||
case Parts.SIDEBAR_PART:
|
||||
return this.sideBarPartView;
|
||||
case Parts.STATUSBAR_PART:
|
||||
return this.statusBarPartView;
|
||||
default:
|
||||
return this.editorPartView;
|
||||
}
|
||||
} else {
|
||||
return this.editorPartView;
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
workbenchGrid = SerializableGrid.deserialize(parsedGrid, { fromJSON }, { proportionalLayout: false });
|
||||
|
||||
const root = workbenchGrid.getViews();
|
||||
const titleBarSection = root.children[0];
|
||||
|
||||
if (isGridBranchNode(titleBarSection) || titleBarSection.view !== this.titleBarPartView) {
|
||||
throw new Error('Bad grid');
|
||||
}
|
||||
|
||||
const middleSection = root.children[1] as GridBranchNode<ISerializableView>;
|
||||
const sideBarPosition = (middleSection.children[0] as GridLeafNode<ISerializableView>).view === this.activityBarPartView ? Position.LEFT : Position.RIGHT;
|
||||
if (sideBarPosition !== this.state.sideBar.position) {
|
||||
throw new Error('Bad Grid');
|
||||
}
|
||||
|
||||
const panelPosition = isGridBranchNode(middleSection.children[2]) || isGridBranchNode(middleSection.children[0]) ? Position.BOTTOM : Position.RIGHT;
|
||||
if (panelPosition !== this.state.panel.position) {
|
||||
throw new Error('Bad Grid');
|
||||
}
|
||||
} catch (err) {
|
||||
workbenchGrid = undefined;
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
|
||||
if (!workbenchGrid) {
|
||||
workbenchGrid = new SerializableGrid(this.editorPartView, { proportionalLayout: false });
|
||||
}
|
||||
const fromJSON = ({ type }: { type: Parts }) => viewMap[type];
|
||||
const workbenchGrid = SerializableGrid.deserialize(
|
||||
this.createGridDescriptor(),
|
||||
{ fromJSON },
|
||||
{ proportionalLayout: false }
|
||||
);
|
||||
|
||||
this.container.prepend(workbenchGrid.element);
|
||||
this.workbenchGrid = workbenchGrid;
|
||||
@@ -791,15 +778,24 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
this.setEditorHidden(!visible, true);
|
||||
}));
|
||||
|
||||
this._register(this.lifecycleService.onBeforeShutdown(beforeShutdownEvent => {
|
||||
beforeShutdownEvent.veto(new Promise((resolve) => {
|
||||
const grid = this.workbenchGrid as SerializableGrid<ISerializableView>;
|
||||
const serializedGrid = grid.serialize();
|
||||
this._register(this.storageService.onWillSaveState(() => {
|
||||
const grid = this.workbenchGrid as SerializableGrid<ISerializableView>;
|
||||
|
||||
this.storageService.store(Storage.GRID_LAYOUT, JSON.stringify(serializedGrid), StorageScope.GLOBAL);
|
||||
const sideBarSize = this.state.sideBar.hidden
|
||||
? grid.getViewCachedVisibleSize(this.sideBarPartView)
|
||||
: grid.getViewSize(this.sideBarPartView).width;
|
||||
|
||||
resolve();
|
||||
}));
|
||||
this.storageService.store(Storage.SIDEBAR_SIZE, sideBarSize, StorageScope.GLOBAL);
|
||||
|
||||
const panelSize = this.state.panel.hidden
|
||||
? grid.getViewCachedVisibleSize(this.panelPartView)
|
||||
: (this.state.panel.position === Position.BOTTOM ? grid.getViewSize(this.panelPartView).height : grid.getViewSize(this.panelPartView).width);
|
||||
|
||||
this.storageService.store(Storage.PANEL_SIZE, panelSize, StorageScope.GLOBAL);
|
||||
|
||||
const gridSize = grid.getViewSize();
|
||||
this.storageService.store(Storage.GRID_WIDTH, gridSize.width, StorageScope.GLOBAL);
|
||||
this.storageService.store(Storage.GRID_HEIGHT, gridSize.height, StorageScope.GLOBAL);
|
||||
}));
|
||||
} else {
|
||||
this.workbenchGrid = instantiationService.createInstance(
|
||||
@@ -828,9 +824,6 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
|
||||
// Layout the grid widget
|
||||
this.workbenchGrid.layout(this._dimension.width, this._dimension.height);
|
||||
|
||||
// Layout grid views
|
||||
this.layoutGrid();
|
||||
} else {
|
||||
this.workbenchGrid.layout(options);
|
||||
}
|
||||
@@ -840,95 +833,6 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
}
|
||||
}
|
||||
|
||||
private layoutGrid(): void {
|
||||
if (!(this.workbenchGrid instanceof Grid)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let panelInGrid = this.workbenchGrid.hasView(this.panelPartView);
|
||||
let sidebarInGrid = this.workbenchGrid.hasView(this.sideBarPartView);
|
||||
let activityBarInGrid = this.workbenchGrid.hasView(this.activityBarPartView);
|
||||
let statusBarInGrid = this.workbenchGrid.hasView(this.statusBarPartView);
|
||||
let titlebarInGrid = this.workbenchGrid.hasView(this.titleBarPartView);
|
||||
|
||||
// Add parts to grid
|
||||
if (!statusBarInGrid) {
|
||||
this.workbenchGrid.addView(this.statusBarPartView, Sizing.Split, this.editorPartView, Direction.Down);
|
||||
statusBarInGrid = true;
|
||||
}
|
||||
|
||||
if (!titlebarInGrid) {
|
||||
this.workbenchGrid.addView(this.titleBarPartView, Sizing.Split, this.editorPartView, Direction.Up);
|
||||
|
||||
titlebarInGrid = true;
|
||||
}
|
||||
|
||||
if (!activityBarInGrid) {
|
||||
this.workbenchGrid.addView(this.activityBarPartView, Sizing.Split, panelInGrid && this.state.sideBar.position === this.state.panel.position ? this.panelPartView : this.editorPartView, this.state.sideBar.position === Position.RIGHT ? Direction.Right : Direction.Left);
|
||||
activityBarInGrid = true;
|
||||
}
|
||||
|
||||
if (!sidebarInGrid) {
|
||||
this.workbenchGrid.addView(this.sideBarPartView, this.state.sideBar.width !== undefined ? this.state.sideBar.width : Sizing.Split, this.activityBarPartView, this.state.sideBar.position === Position.LEFT ? Direction.Right : Direction.Left);
|
||||
sidebarInGrid = true;
|
||||
}
|
||||
|
||||
if (!panelInGrid) {
|
||||
this.workbenchGrid.addView(this.panelPartView, Sizing.Split, this.editorPartView, this.state.panel.position === Position.BOTTOM ? Direction.Down : Direction.Right);
|
||||
panelInGrid = true;
|
||||
}
|
||||
|
||||
// Hide parts
|
||||
if (this.state.panel.hidden) {
|
||||
this.workbenchGrid.setViewVisible(this.panelPartView, false);
|
||||
}
|
||||
|
||||
if (this.state.statusBar.hidden) {
|
||||
this.workbenchGrid.setViewVisible(this.statusBarPartView, false);
|
||||
}
|
||||
|
||||
if (titlebarInGrid && !this.isVisible(Parts.TITLEBAR_PART)) {
|
||||
this.workbenchGrid.setViewVisible(this.titleBarPartView, false);
|
||||
}
|
||||
|
||||
if (this.state.activityBar.hidden) {
|
||||
this.workbenchGrid.setViewVisible(this.activityBarPartView, false);
|
||||
}
|
||||
|
||||
if (this.state.sideBar.hidden) {
|
||||
this.workbenchGrid.setViewVisible(this.sideBarPartView, false);
|
||||
}
|
||||
|
||||
if (this.state.editor.hidden) {
|
||||
this.workbenchGrid.setViewVisible(this.editorPartView, false);
|
||||
}
|
||||
|
||||
// Show visible parts
|
||||
if (!this.state.editor.hidden) {
|
||||
this.workbenchGrid.setViewVisible(this.editorPartView, true);
|
||||
}
|
||||
|
||||
if (!this.state.statusBar.hidden) {
|
||||
this.workbenchGrid.setViewVisible(this.statusBarPartView, true);
|
||||
}
|
||||
|
||||
if (this.isVisible(Parts.TITLEBAR_PART)) {
|
||||
this.workbenchGrid.setViewVisible(this.titleBarPartView, true);
|
||||
}
|
||||
|
||||
if (!this.state.activityBar.hidden) {
|
||||
this.workbenchGrid.setViewVisible(this.activityBarPartView, true);
|
||||
}
|
||||
|
||||
if (!this.state.sideBar.hidden) {
|
||||
this.workbenchGrid.setViewVisible(this.sideBarPartView, true);
|
||||
}
|
||||
|
||||
if (!this.state.panel.hidden) {
|
||||
this.workbenchGrid.setViewVisible(this.panelPartView, true);
|
||||
}
|
||||
}
|
||||
|
||||
isEditorLayoutCentered(): boolean {
|
||||
return this.state.editor.centered;
|
||||
}
|
||||
@@ -1019,41 +923,60 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
setActivityBarHidden(hidden: boolean, skipLayout?: boolean): void {
|
||||
this.state.activityBar.hidden = hidden;
|
||||
|
||||
// Propagate to grid
|
||||
if (this.workbenchGrid instanceof Grid) {
|
||||
this.workbenchGrid.setViewVisible(this.activityBarPartView, !hidden);
|
||||
}
|
||||
|
||||
// Layout
|
||||
if (!skipLayout) {
|
||||
if (this.workbenchGrid instanceof Grid) {
|
||||
this.layout();
|
||||
} else {
|
||||
if (!(this.workbenchGrid instanceof Grid)) {
|
||||
this.workbenchGrid.layout();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setEditorHidden(hidden: boolean, skipLayout?: boolean): void {
|
||||
if (!(this.workbenchGrid instanceof Grid) || hidden === this.state.editor.hidden) {
|
||||
if (!(this.workbenchGrid instanceof Grid)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.state.editor.hidden = hidden;
|
||||
|
||||
// The editor and the panel cannot be hidden at the same time
|
||||
if (this.state.editor.hidden && this.state.panel.hidden) {
|
||||
this.setPanelHidden(false, true);
|
||||
// Adjust CSS
|
||||
if (hidden) {
|
||||
addClass(this.container, Classes.EDITOR_HIDDEN);
|
||||
} else {
|
||||
removeClass(this.container, Classes.EDITOR_HIDDEN);
|
||||
}
|
||||
|
||||
if (!skipLayout) {
|
||||
this.layout();
|
||||
// Propagate to grid
|
||||
this.workbenchGrid.setViewVisible(this.editorPartView, !hidden);
|
||||
|
||||
// The editor and panel cannot be hidden at the same time
|
||||
if (hidden && this.state.panel.hidden) {
|
||||
this.setPanelHidden(false, true);
|
||||
}
|
||||
}
|
||||
|
||||
getLayoutClasses(): string[] {
|
||||
return coalesce([
|
||||
this.state.sideBar.hidden ? Classes.SIDEBAR_HIDDEN : undefined,
|
||||
this.state.editor.hidden ? Classes.EDITOR_HIDDEN : undefined,
|
||||
this.state.panel.hidden ? Classes.PANEL_HIDDEN : undefined,
|
||||
this.state.statusBar.hidden ? Classes.STATUSBAR_HIDDEN : undefined,
|
||||
this.state.fullscreen ? Classes.FULLSCREEN : undefined
|
||||
]);
|
||||
}
|
||||
|
||||
setSideBarHidden(hidden: boolean, skipLayout?: boolean): void {
|
||||
this.state.sideBar.hidden = hidden;
|
||||
|
||||
// Adjust CSS
|
||||
if (hidden) {
|
||||
addClass(this.container, 'nosidebar');
|
||||
addClass(this.container, Classes.SIDEBAR_HIDDEN);
|
||||
} else {
|
||||
removeClass(this.container, 'nosidebar');
|
||||
removeClass(this.container, Classes.SIDEBAR_HIDDEN);
|
||||
}
|
||||
|
||||
// If sidebar becomes hidden, also hide the current active Viewlet if any
|
||||
@@ -1080,6 +1003,11 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
}
|
||||
}
|
||||
|
||||
// Propagate to grid
|
||||
if (this.workbenchGrid instanceof Grid) {
|
||||
this.workbenchGrid.setViewVisible(this.sideBarPartView, !hidden);
|
||||
}
|
||||
|
||||
// Remember in settings
|
||||
const defaultHidden = this.contextService.getWorkbenchState() === WorkbenchState.EMPTY;
|
||||
if (hidden !== defaultHidden) {
|
||||
@@ -1090,9 +1018,7 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
|
||||
// Layout
|
||||
if (!skipLayout) {
|
||||
if (this.workbenchGrid instanceof Grid) {
|
||||
this.layout();
|
||||
} else {
|
||||
if (!(this.workbenchGrid instanceof Grid)) {
|
||||
this.workbenchGrid.layout();
|
||||
}
|
||||
}
|
||||
@@ -1103,9 +1029,9 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
|
||||
// Adjust CSS
|
||||
if (hidden) {
|
||||
addClass(this.container, 'nopanel');
|
||||
addClass(this.container, Classes.PANEL_HIDDEN);
|
||||
} else {
|
||||
removeClass(this.container, 'nopanel');
|
||||
removeClass(this.container, Classes.PANEL_HIDDEN);
|
||||
}
|
||||
|
||||
// If panel part becomes hidden, also hide the current active panel if any
|
||||
@@ -1123,6 +1049,11 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
}
|
||||
}
|
||||
|
||||
// Propagate to grid
|
||||
if (this.workbenchGrid instanceof Grid) {
|
||||
this.workbenchGrid.setViewVisible(this.panelPartView, !hidden);
|
||||
}
|
||||
|
||||
// Remember in settings
|
||||
if (!hidden) {
|
||||
this.storageService.store(Storage.PANEL_HIDDEN, 'false', StorageScope.WORKSPACE);
|
||||
@@ -1137,9 +1068,7 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
|
||||
// Layout
|
||||
if (!skipLayout) {
|
||||
if (this.workbenchGrid instanceof Grid) {
|
||||
this.layout();
|
||||
} else {
|
||||
if (!(this.workbenchGrid instanceof Grid)) {
|
||||
this.workbenchGrid.layout();
|
||||
}
|
||||
}
|
||||
@@ -1147,33 +1076,15 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
|
||||
toggleMaximizedPanel(): void {
|
||||
if (this.workbenchGrid instanceof Grid) {
|
||||
const curSize = this.workbenchGrid.getViewSize(this.panelPartView);
|
||||
const size = { ...curSize };
|
||||
|
||||
const size = this.workbenchGrid.getViewSize(this.panelPartView);
|
||||
if (!this.isPanelMaximized()) {
|
||||
if (this.state.panel.position === Position.BOTTOM) {
|
||||
size.height = this.panelPartView.maximumHeight;
|
||||
this.state.panel.sizeBeforeMaximize = curSize.height;
|
||||
} else {
|
||||
size.width = this.panelPartView.maximumWidth;
|
||||
this.state.panel.sizeBeforeMaximize = curSize.width;
|
||||
}
|
||||
|
||||
this.state.panel.sizeBeforeMaximize = this.state.panel.position === Position.BOTTOM ? size.height : size.width;
|
||||
this.storageService.store(Storage.PANEL_SIZE_BEFORE_MAXIMIZED, this.state.panel.sizeBeforeMaximize, StorageScope.GLOBAL);
|
||||
this.setEditorHidden(true);
|
||||
} else {
|
||||
if (this.state.panel.position === Position.BOTTOM) {
|
||||
size.height = this.state.panel.sizeBeforeMaximize;
|
||||
} else {
|
||||
size.width = this.state.panel.sizeBeforeMaximize;
|
||||
}
|
||||
|
||||
// Unhide the editor if needed
|
||||
if (this.state.editor.hidden) {
|
||||
this.setEditorHidden(false);
|
||||
}
|
||||
this.setEditorHidden(false);
|
||||
this.workbenchGrid.resizeView(this.panelPartView, { width: this.state.panel.position === Position.BOTTOM ? size.width : this.state.panel.sizeBeforeMaximize, height: this.state.panel.position === Position.BOTTOM ? this.state.panel.sizeBeforeMaximize : size.height });
|
||||
}
|
||||
|
||||
this.workbenchGrid.resizeView(this.panelPartView, size);
|
||||
} else {
|
||||
this.workbenchGrid.layout({ toggleMaximizedPanel: true, source: Parts.PANEL_PART });
|
||||
}
|
||||
@@ -1185,16 +1096,7 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
}
|
||||
|
||||
if (this.workbenchGrid instanceof Grid) {
|
||||
try {
|
||||
// The panel is maximum when the editor is minimum
|
||||
if (this.state.panel.position === Position.BOTTOM) {
|
||||
return this.workbenchGrid.getViewSize(this.editorPartView).height <= this.editorPartView.minimumHeight;
|
||||
} else {
|
||||
return this.workbenchGrid.getViewSize(this.editorPartView).width <= this.editorPartView.minimumWidth;
|
||||
}
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
return this.state.editor.hidden;
|
||||
} else {
|
||||
return this.workbenchGrid.isPanelMaximized();
|
||||
}
|
||||
@@ -1211,8 +1113,7 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
// Layout
|
||||
if (!skipLayout) {
|
||||
if (this.workbenchGrid instanceof Grid) {
|
||||
const dimensions = getClientArea(this.parent);
|
||||
this.workbenchGrid.layout(dimensions.width, dimensions.height);
|
||||
this.workbenchGrid.setViewVisible(this.titleBarPartView, this.isVisible(Parts.TITLEBAR_PART));
|
||||
} else {
|
||||
this.workbenchGrid.layout();
|
||||
}
|
||||
@@ -1228,13 +1129,12 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
return this.state.panel.position;
|
||||
}
|
||||
|
||||
setPanelPosition(position: Position): void {
|
||||
const panelPart = this.getPart(Parts.PANEL_PART);
|
||||
|
||||
setPanelPosition(position: Position.BOTTOM | Position.RIGHT): void {
|
||||
if (this.state.panel.hidden) {
|
||||
this.setPanelHidden(false, true /* Skip Layout */);
|
||||
this.setPanelHidden(false);
|
||||
}
|
||||
|
||||
const panelPart = this.getPart(Parts.PANEL_PART);
|
||||
const newPositionValue = (position === Position.BOTTOM) ? 'bottom' : 'right';
|
||||
const oldPositionValue = (this.state.panel.position === Position.BOTTOM) ? 'bottom' : 'right';
|
||||
this.state.panel.position = position;
|
||||
@@ -1258,8 +1158,17 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
|
||||
// Layout
|
||||
if (this.workbenchGrid instanceof Grid) {
|
||||
this.workbenchGrid.removeView(this.panelPartView);
|
||||
this.layout();
|
||||
const size = this.workbenchGrid.getViewSize(this.panelPartView);
|
||||
const sideBarSize = this.workbenchGrid.getViewSize(this.sideBarPartView);
|
||||
|
||||
if (position === Position.BOTTOM) {
|
||||
this.workbenchGrid.moveView(this.panelPartView, this.state.editor.hidden ? size.height : size.width, this.editorPartView, Direction.Down);
|
||||
} else {
|
||||
this.workbenchGrid.moveView(this.panelPartView, this.state.editor.hidden ? size.width : size.height, this.editorPartView, Direction.Right);
|
||||
}
|
||||
|
||||
// Reset sidebar to original size before shifting the panel
|
||||
this.workbenchGrid.resizeView(this.sideBarPartView, sideBarSize);
|
||||
} else {
|
||||
this.workbenchGrid.layout();
|
||||
}
|
||||
@@ -1267,9 +1176,89 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
this._onPanelPositionChange.fire(positionToString(this.state.panel.position));
|
||||
}
|
||||
|
||||
private createGridDescriptor(): ISerializedGrid {
|
||||
const width = this.storageService.getNumber(Storage.GRID_WIDTH, StorageScope.GLOBAL, 600);
|
||||
const height = this.storageService.getNumber(Storage.GRID_HEIGHT, StorageScope.GLOBAL, 400);
|
||||
const sideBarSize = this.storageService.getNumber(Storage.SIDEBAR_SIZE, StorageScope.GLOBAL, 300);
|
||||
const panelSize = this.storageService.getNumber(Storage.PANEL_SIZE, StorageScope.GLOBAL, 300);
|
||||
|
||||
const titleBarHeight = this.titleBarPartView.minimumHeight;
|
||||
const statusBarHeight = this.statusBarPartView.minimumHeight;
|
||||
const activityBarWidth = this.activityBarPartView.minimumWidth;
|
||||
const middleSectionHeight = height - titleBarHeight - statusBarHeight;
|
||||
const editorSectionWidth = width - (this.state.activityBar.hidden ? 0 : activityBarWidth) - (this.state.sideBar.hidden ? 0 : sideBarSize);
|
||||
|
||||
const activityBarNode: ISerializedLeafNode = {
|
||||
type: 'leaf',
|
||||
data: { type: Parts.ACTIVITYBAR_PART },
|
||||
size: activityBarWidth,
|
||||
visible: !this.state.activityBar.hidden
|
||||
};
|
||||
|
||||
const sideBarNode: ISerializedLeafNode = {
|
||||
type: 'leaf',
|
||||
data: { type: Parts.SIDEBAR_PART },
|
||||
size: sideBarSize,
|
||||
visible: !this.state.sideBar.hidden
|
||||
};
|
||||
|
||||
const editorNode: ISerializedLeafNode = {
|
||||
type: 'leaf',
|
||||
data: { type: Parts.EDITOR_PART },
|
||||
size: this.state.panel.position === Position.BOTTOM ? middleSectionHeight - (this.state.panel.hidden ? 0 : panelSize) : editorSectionWidth - (this.state.panel.hidden ? 0 : panelSize)
|
||||
};
|
||||
|
||||
const panelNode: ISerializedLeafNode = {
|
||||
type: 'leaf',
|
||||
data: { type: Parts.PANEL_PART },
|
||||
size: panelSize,
|
||||
visible: !this.state.panel.hidden
|
||||
};
|
||||
|
||||
const editorSectionNode: ISerializedNode[] = this.state.panel.position === Position.BOTTOM
|
||||
? [{ type: 'branch', data: [editorNode, panelNode], size: editorSectionWidth }]
|
||||
: [editorNode, panelNode];
|
||||
|
||||
const middleSection: ISerializedNode[] = this.state.sideBar.position === Position.LEFT
|
||||
? [activityBarNode, sideBarNode, ...editorSectionNode]
|
||||
: [...editorSectionNode, sideBarNode, activityBarNode];
|
||||
|
||||
const result: ISerializedGrid = {
|
||||
root: {
|
||||
type: 'branch',
|
||||
size: width,
|
||||
data: [
|
||||
{
|
||||
type: 'leaf',
|
||||
data: { type: Parts.TITLEBAR_PART },
|
||||
size: titleBarHeight,
|
||||
visible: this.isVisible(Parts.TITLEBAR_PART)
|
||||
},
|
||||
{
|
||||
type: 'branch',
|
||||
data: middleSection,
|
||||
size: middleSectionHeight
|
||||
},
|
||||
{
|
||||
type: 'leaf',
|
||||
data: { type: Parts.STATUSBAR_PART },
|
||||
size: statusBarHeight,
|
||||
visible: !this.state.statusBar.hidden
|
||||
}
|
||||
]
|
||||
},
|
||||
orientation: Orientation.VERTICAL,
|
||||
width,
|
||||
height
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
super.dispose();
|
||||
|
||||
this.disposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ export class PanelDescriptor extends CompositeDescriptor<Panel> {
|
||||
}
|
||||
|
||||
export class PanelRegistry extends CompositeRegistry<Panel> {
|
||||
private defaultPanelId: string;
|
||||
private defaultPanelId!: string;
|
||||
|
||||
/**
|
||||
* Registers a panel to the platform.
|
||||
|
||||
@@ -48,7 +48,7 @@ interface ICachedViewlet {
|
||||
|
||||
export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
|
||||
_serviceBrand: ServiceIdentifier<any>;
|
||||
_serviceBrand!: ServiceIdentifier<any>;
|
||||
|
||||
private static readonly ACTION_HEIGHT = 48;
|
||||
private static readonly PINNED_VIEWLETS = 'workbench.activity.pinnedViewlets';
|
||||
|
||||
@@ -46,10 +46,10 @@ export interface ICompositeBarOptions {
|
||||
|
||||
export class CompositeBar extends Widget implements ICompositeBar {
|
||||
|
||||
private dimension: Dimension;
|
||||
private dimension: Dimension | undefined;
|
||||
|
||||
private compositeSwitcherBar: ActionBar;
|
||||
private compositeOverflowAction: CompositeOverflowActivityAction | null;
|
||||
private compositeSwitcherBar!: ActionBar;
|
||||
private compositeOverflowAction: CompositeOverflowActivityAction | undefined;
|
||||
private compositeOverflowActionViewItem: CompositeOverflowActivityActionViewItem | undefined;
|
||||
|
||||
private model: CompositeBarModel;
|
||||
@@ -343,7 +343,7 @@ export class CompositeBar extends Widget implements ICompositeBar {
|
||||
this.compositeSwitcherBar.pull(this.compositeSwitcherBar.length() - 1);
|
||||
|
||||
this.compositeOverflowAction.dispose();
|
||||
this.compositeOverflowAction = null;
|
||||
this.compositeOverflowAction = undefined;
|
||||
|
||||
if (this.compositeOverflowActionViewItem) {
|
||||
this.compositeOverflowActionViewItem.dispose();
|
||||
@@ -460,7 +460,7 @@ interface ICompositeBarModelItem extends ICompositeBarItem {
|
||||
|
||||
class CompositeBarModel {
|
||||
|
||||
private _items: ICompositeBarModelItem[];
|
||||
private _items: ICompositeBarModelItem[] = [];
|
||||
private readonly options: ICompositeBarOptions;
|
||||
activeItem?: ICompositeBarModelItem;
|
||||
|
||||
|
||||
@@ -124,12 +124,12 @@ export interface IActivityActionViewItemOptions extends IBaseActionViewItemOptio
|
||||
}
|
||||
|
||||
export class ActivityActionViewItem extends BaseActionViewItem {
|
||||
protected container: HTMLElement;
|
||||
protected label: HTMLElement;
|
||||
protected badge: HTMLElement;
|
||||
protected options: IActivityActionViewItemOptions;
|
||||
protected container!: HTMLElement;
|
||||
protected label!: HTMLElement;
|
||||
protected badge!: HTMLElement;
|
||||
protected options!: IActivityActionViewItemOptions;
|
||||
|
||||
private badgeContent: HTMLElement;
|
||||
private badgeContent: HTMLElement | undefined;
|
||||
private readonly badgeDisposable = this._register(new MutableDisposable());
|
||||
private mouseUpTimeout: any;
|
||||
|
||||
@@ -347,7 +347,7 @@ export class CompositeOverflowActivityAction extends ActivityAction {
|
||||
}
|
||||
|
||||
export class CompositeOverflowActivityActionViewItem extends ActivityActionViewItem {
|
||||
private actions: Action[];
|
||||
private actions: Action[] | undefined;
|
||||
|
||||
constructor(
|
||||
action: ActivityAction,
|
||||
@@ -371,8 +371,8 @@ export class CompositeOverflowActivityActionViewItem extends ActivityActionViewI
|
||||
|
||||
this.contextMenuService.showContextMenu({
|
||||
getAnchor: () => this.element!,
|
||||
getActions: () => this.actions,
|
||||
onHide: () => dispose(this.actions)
|
||||
getActions: () => this.actions!,
|
||||
onHide: () => dispose(this.actions!)
|
||||
});
|
||||
}
|
||||
|
||||
@@ -402,7 +402,9 @@ export class CompositeOverflowActivityActionViewItem extends ActivityActionViewI
|
||||
dispose(): void {
|
||||
super.dispose();
|
||||
|
||||
this.actions = dispose(this.actions);
|
||||
if (this.actions) {
|
||||
this.actions = dispose(this.actions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -431,7 +433,7 @@ export class CompositeActionViewItem extends ActivityActionViewItem {
|
||||
|
||||
private static manageExtensionAction: ManageExtensionAction;
|
||||
|
||||
private compositeActivity: IActivity | null;
|
||||
private compositeActivity: IActivity | undefined;
|
||||
private compositeTransfer: LocalSelectionTransfer<DraggedCompositeIdentifier>;
|
||||
|
||||
constructor(
|
||||
@@ -454,7 +456,7 @@ export class CompositeActionViewItem extends ActivityActionViewItem {
|
||||
CompositeActionViewItem.manageExtensionAction = instantiationService.createInstance(ManageExtensionAction);
|
||||
}
|
||||
|
||||
this._register(compositeActivityAction.onDidChangeActivity(() => { this.compositeActivity = null; this.updateActivity(); }, this));
|
||||
this._register(compositeActivityAction.onDidChangeActivity(() => { this.compositeActivity = undefined; this.updateActivity(); }, this));
|
||||
}
|
||||
|
||||
protected get activity(): IActivity {
|
||||
|
||||
@@ -58,18 +58,18 @@ export abstract class CompositePart<T extends Composite> extends Part {
|
||||
protected readonly onDidCompositeOpen = this._register(new Emitter<{ composite: IComposite, focus: boolean }>());
|
||||
protected readonly onDidCompositeClose = this._register(new Emitter<IComposite>());
|
||||
|
||||
protected toolBar: ToolBar;
|
||||
protected toolBar!: ToolBar;
|
||||
|
||||
private mapCompositeToCompositeContainer = new Map<string, HTMLElement>();
|
||||
private mapActionsBindingToComposite = new Map<string, () => void>();
|
||||
private activeComposite: Composite | null;
|
||||
private lastActiveCompositeId: string;
|
||||
private instantiatedCompositeItems: Map<string, CompositeItem>;
|
||||
private titleLabel: ICompositeTitleLabel;
|
||||
private progressBar: ProgressBar;
|
||||
private contentAreaSize: Dimension;
|
||||
private titleLabel!: ICompositeTitleLabel;
|
||||
private progressBar!: ProgressBar;
|
||||
private contentAreaSize: Dimension | undefined;
|
||||
private readonly telemetryActionsListener = this._register(new MutableDisposable());
|
||||
private currentCompositeOpenToken: string;
|
||||
private currentCompositeOpenToken: string | undefined;
|
||||
|
||||
constructor(
|
||||
private notificationService: INotificationService,
|
||||
|
||||
@@ -29,7 +29,7 @@ export interface IBreadcrumbsService {
|
||||
|
||||
export class BreadcrumbsService implements IBreadcrumbsService {
|
||||
|
||||
_serviceBrand: ServiceIdentifier<any>;
|
||||
_serviceBrand: any;
|
||||
|
||||
private readonly _map = new Map<number, BreadcrumbsWidget>();
|
||||
|
||||
@@ -55,8 +55,8 @@ registerSingleton(IBreadcrumbsService, BreadcrumbsService, true);
|
||||
|
||||
export abstract class BreadcrumbsConfig<T> {
|
||||
|
||||
name: string;
|
||||
onDidChange: Event<void>;
|
||||
abstract get name(): string;
|
||||
abstract get onDidChange(): Event<void>;
|
||||
|
||||
abstract getValue(overrides?: IConfigurationOverrides): T;
|
||||
abstract updateValue(value: T, overrides?: IConfigurationOverrides): Promise<void>;
|
||||
|
||||
@@ -56,11 +56,11 @@ export abstract class BreadcrumbsPicker {
|
||||
|
||||
protected readonly _disposables = new DisposableStore();
|
||||
protected readonly _domNode: HTMLDivElement;
|
||||
protected _arrow: HTMLDivElement;
|
||||
protected _treeContainer: HTMLDivElement;
|
||||
protected _tree: Tree<any, any>;
|
||||
protected _arrow!: HTMLDivElement;
|
||||
protected _treeContainer!: HTMLDivElement;
|
||||
protected _tree!: Tree<any, any>;
|
||||
protected _fakeEvent = new UIEvent('fakeEvent');
|
||||
protected _layoutInfo: ILayoutInfo;
|
||||
protected _layoutInfo!: ILayoutInfo;
|
||||
|
||||
private readonly _onDidPickElement = new Emitter<SelectEvent>();
|
||||
readonly onDidPickElement: Event<SelectEvent> = this._onDidPickElement.event;
|
||||
|
||||
@@ -36,7 +36,7 @@ import {
|
||||
SplitEditorUpAction, SplitEditorDownAction, MoveEditorToLeftGroupAction, MoveEditorToRightGroupAction, MoveEditorToAboveGroupAction, MoveEditorToBelowGroupAction, CloseAllEditorGroupsAction,
|
||||
JoinAllGroupsAction, FocusLeftGroup, FocusAboveGroup, FocusRightGroup, FocusBelowGroup, EditorLayoutSingleAction, EditorLayoutTwoColumnsAction, EditorLayoutThreeColumnsAction, EditorLayoutTwoByTwoGridAction,
|
||||
EditorLayoutTwoRowsAction, EditorLayoutThreeRowsAction, EditorLayoutTwoColumnsBottomAction, EditorLayoutTwoRowsRightAction, NewEditorGroupLeftAction, NewEditorGroupRightAction,
|
||||
NewEditorGroupAboveAction, NewEditorGroupBelowAction, SplitEditorOrthogonalAction, CloseEditorInAllGroupsAction, NavigateToLastEditLocationAction
|
||||
NewEditorGroupAboveAction, NewEditorGroupBelowAction, SplitEditorOrthogonalAction, CloseEditorInAllGroupsAction, NavigateToLastEditLocationAction, ToggleGroupSizesAction
|
||||
} from 'vs/workbench/browser/parts/editor/editorActions';
|
||||
import * as editorCommands from 'vs/workbench/browser/parts/editor/editorCommands';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
@@ -339,6 +339,7 @@ registry.registerWorkbenchAction(new SyncActionDescriptor(JoinTwoGroupsAction, J
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(JoinAllGroupsAction, JoinAllGroupsAction.ID, JoinAllGroupsAction.LABEL), 'View: Join All Editor Groups', category);
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(NavigateBetweenGroupsAction, NavigateBetweenGroupsAction.ID, NavigateBetweenGroupsAction.LABEL), 'View: Navigate Between Editor Groups', category);
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(ResetGroupSizesAction, ResetGroupSizesAction.ID, ResetGroupSizesAction.LABEL), 'View: Reset Editor Group Sizes', category);
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(ToggleGroupSizesAction, ToggleGroupSizesAction.ID, ToggleGroupSizesAction.LABEL), 'View: Toggle Editor Group Sizes', category);
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(MaximizeGroupAction, MaximizeGroupAction.ID, MaximizeGroupAction.LABEL), 'View: Maximize Editor Group and Hide Side Bar', category);
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(MinimizeOtherGroupsAction, MinimizeOtherGroupsAction.ID, MinimizeOtherGroupsAction.LABEL), 'View: Maximize Editor Group', category);
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(MoveEditorLeftInGroupAction, MoveEditorLeftInGroupAction.ID, MoveEditorLeftInGroupAction.LABEL, { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.PageUp, mac: { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.LeftArrow) } }), 'View: Move Editor Left', category);
|
||||
|
||||
@@ -81,12 +81,15 @@ export interface IEditorOpeningEvent extends IEditorIdentifier {
|
||||
}
|
||||
|
||||
export interface IEditorGroupsAccessor {
|
||||
|
||||
readonly groups: IEditorGroupView[];
|
||||
readonly activeGroup: IEditorGroupView;
|
||||
|
||||
readonly partOptions: IEditorPartOptions;
|
||||
readonly onDidEditorPartOptionsChange: Event<IEditorPartOptionsChangeEvent>;
|
||||
|
||||
readonly onDidVisibilityChange: Event<boolean>;
|
||||
|
||||
getGroup(identifier: GroupIdentifier): IEditorGroupView | undefined;
|
||||
getGroups(order: GroupsOrder): IEditorGroupView[];
|
||||
|
||||
@@ -106,6 +109,9 @@ export interface IEditorGroupView extends IDisposable, ISerializableView, IEdito
|
||||
readonly whenRestored: Promise<void>;
|
||||
readonly disposed: boolean;
|
||||
|
||||
readonly isEmpty: boolean;
|
||||
readonly isMinimized: boolean;
|
||||
|
||||
readonly onDidFocus: Event<void>;
|
||||
readonly onWillDispose: Event<void>;
|
||||
readonly onWillOpenEditor: Event<IEditorOpeningEvent>;
|
||||
@@ -113,9 +119,10 @@ export interface IEditorGroupView extends IDisposable, ISerializableView, IEdito
|
||||
readonly onWillCloseEditor: Event<IEditorCloseEvent>;
|
||||
readonly onDidCloseEditor: Event<IEditorCloseEvent>;
|
||||
|
||||
isEmpty(): boolean;
|
||||
setActive(isActive: boolean): void;
|
||||
setLabel(label: string): void;
|
||||
|
||||
notifyIndexChanged(newIndex: number): void;
|
||||
|
||||
relayout(): void;
|
||||
}
|
||||
|
||||
|
||||
@@ -880,6 +880,22 @@ export class ResetGroupSizesAction extends Action {
|
||||
}
|
||||
}
|
||||
|
||||
export class ToggleGroupSizesAction extends Action {
|
||||
|
||||
static readonly ID = 'workbench.action.toggleEditorWidths';
|
||||
static readonly LABEL = nls.localize('toggleEditorWidths', "Toggle Editor Group Sizes");
|
||||
|
||||
constructor(id: string, label: string, @IEditorGroupsService private readonly editorGroupService: IEditorGroupsService) {
|
||||
super(id, label);
|
||||
}
|
||||
|
||||
run(): Promise<any> {
|
||||
this.editorGroupService.arrangeGroups(GroupsArrangement.TOGGLE);
|
||||
|
||||
return Promise.resolve(false);
|
||||
}
|
||||
}
|
||||
|
||||
export class MaximizeGroupAction extends Action {
|
||||
|
||||
static readonly ID = 'workbench.action.maximizeEditor';
|
||||
|
||||
@@ -221,6 +221,12 @@ export class EditorControl extends Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
setVisible(visible: boolean): void {
|
||||
if (this._activeControl) {
|
||||
this._activeControl.setVisible(visible, this.groupView);
|
||||
}
|
||||
}
|
||||
|
||||
layout(dimension: Dimension): void {
|
||||
this.dimension = dimension;
|
||||
|
||||
|
||||
@@ -409,7 +409,7 @@ class DropOverlay extends Themable {
|
||||
}
|
||||
|
||||
private getOverlayOffsetHeight(): number {
|
||||
if (!this.groupView.isEmpty() && this.accessor.partOptions.showTabs) {
|
||||
if (!this.groupView.isEmpty && this.accessor.partOptions.showTabs) {
|
||||
return EDITOR_TITLE_HEIGHT; // show overlay below title if group shows tabs
|
||||
}
|
||||
|
||||
|
||||
@@ -58,16 +58,16 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
|
||||
//#region factory
|
||||
|
||||
static createNew(accessor: IEditorGroupsAccessor, label: string, instantiationService: IInstantiationService): IEditorGroupView {
|
||||
return instantiationService.createInstance(EditorGroupView, accessor, null, label);
|
||||
static createNew(accessor: IEditorGroupsAccessor, index: number, instantiationService: IInstantiationService): IEditorGroupView {
|
||||
return instantiationService.createInstance(EditorGroupView, accessor, null, index);
|
||||
}
|
||||
|
||||
static createFromSerialized(serialized: ISerializedEditorGroup, accessor: IEditorGroupsAccessor, label: string, instantiationService: IInstantiationService): IEditorGroupView {
|
||||
return instantiationService.createInstance(EditorGroupView, accessor, serialized, label);
|
||||
static createFromSerialized(serialized: ISerializedEditorGroup, accessor: IEditorGroupsAccessor, index: number, instantiationService: IInstantiationService): IEditorGroupView {
|
||||
return instantiationService.createInstance(EditorGroupView, accessor, serialized, index);
|
||||
}
|
||||
|
||||
static createCopy(copyFrom: IEditorGroupView, accessor: IEditorGroupsAccessor, label: string, instantiationService: IInstantiationService): IEditorGroupView {
|
||||
return instantiationService.createInstance(EditorGroupView, accessor, copyFrom, label);
|
||||
static createCopy(copyFrom: IEditorGroupView, accessor: IEditorGroupsAccessor, index: number, instantiationService: IInstantiationService): IEditorGroupView {
|
||||
return instantiationService.createInstance(EditorGroupView, accessor, copyFrom, index);
|
||||
}
|
||||
|
||||
//#endregion
|
||||
@@ -123,7 +123,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
constructor(
|
||||
private accessor: IEditorGroupsAccessor,
|
||||
from: IEditorGroupView | ISerializedEditorGroup,
|
||||
private _label: string,
|
||||
private _index: number,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@IContextKeyService private readonly contextKeyService: IContextKeyService,
|
||||
@IThemeService themeService: IThemeService,
|
||||
@@ -256,7 +256,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
|
||||
// Open new file via doubleclick on empty container
|
||||
this._register(addDisposableListener(this.element, EventType.DBLCLICK, e => {
|
||||
if (this.isEmpty()) {
|
||||
if (this.isEmpty) {
|
||||
EventHelper.stop(e);
|
||||
// {{SQL CARBON EDIT}}
|
||||
this.commandService.executeCommand(GlobalNewUntitledFileAction.ID).then(undefined, err => this.notificationService.warn(err));
|
||||
@@ -265,7 +265,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
|
||||
// Close empty editor group via middle mouse click
|
||||
this._register(addDisposableListener(this.element, EventType.MOUSE_UP, e => {
|
||||
if (this.isEmpty() && e.button === 1 /* Middle Button */) {
|
||||
if (this.isEmpty && e.button === 1 /* Middle Button */) {
|
||||
EventHelper.stop(e);
|
||||
|
||||
this.accessor.removeGroup(this);
|
||||
@@ -314,7 +314,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
}
|
||||
|
||||
private onShowContainerContextMenu(menu: IMenu, e?: MouseEvent): void {
|
||||
if (!this.isEmpty()) {
|
||||
if (!this.isEmpty) {
|
||||
return; // only for empty editor groups
|
||||
}
|
||||
|
||||
@@ -345,7 +345,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
// Container
|
||||
const containerFocusTracker = this._register(trackFocus(this.element));
|
||||
this._register(containerFocusTracker.onDidFocus(() => {
|
||||
if (this.isEmpty()) {
|
||||
if (this.isEmpty) {
|
||||
this._onDidFocus.fire(); // only when empty to prevent accident focus
|
||||
}
|
||||
}));
|
||||
@@ -387,7 +387,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
private updateContainer(): void {
|
||||
|
||||
// Empty Container: add some empty container attributes
|
||||
if (this.isEmpty()) {
|
||||
if (this.isEmpty) {
|
||||
addClass(this.element, 'empty');
|
||||
this.element.tabIndex = 0;
|
||||
this.element.setAttribute('aria-label', localize('emptyEditorGroup', "{0} (empty)", this.label));
|
||||
@@ -474,6 +474,9 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
|
||||
// Option Changes
|
||||
this._register(this.accessor.onDidEditorPartOptionsChange(e => this.onDidEditorPartOptionsChange(e)));
|
||||
|
||||
// Visibility
|
||||
this._register(this.accessor.onDidVisibilityChange(e => this.onDidVisibilityChange(e)));
|
||||
}
|
||||
|
||||
private onDidEditorPin(editor: EditorInput): void {
|
||||
@@ -597,8 +600,12 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
|
||||
// Title control Switch between showing tabs <=> not showing tabs
|
||||
if (event.oldPartOptions.showTabs !== event.newPartOptions.showTabs) {
|
||||
this.createTitleAreaControl();
|
||||
|
||||
// Recreate and layout control
|
||||
this.createTitleAreaControl();
|
||||
this.layoutTitleAreaControl();
|
||||
|
||||
// Ensure to show active editor if any
|
||||
if (this._group.activeEditor) {
|
||||
this.titleAreaControl.openEditor(this._group.activeEditor);
|
||||
}
|
||||
@@ -641,6 +648,12 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
this._onDidGroupChange.fire({ kind: GroupChangeKind.EDITOR_LABEL, editor });
|
||||
}
|
||||
|
||||
private onDidVisibilityChange(visible: boolean): void {
|
||||
|
||||
// Forward to editor control
|
||||
this.editorControl.setVisible(visible);
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//region IEditorGroupView
|
||||
@@ -649,8 +662,12 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
return this._group;
|
||||
}
|
||||
|
||||
get index(): number {
|
||||
return this._index;
|
||||
}
|
||||
|
||||
get label(): string {
|
||||
return this._label;
|
||||
return localize('groupLabel', "Group {0}", this._index + 1);
|
||||
}
|
||||
|
||||
get disposed(): boolean {
|
||||
@@ -661,10 +678,22 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
return this._whenRestored;
|
||||
}
|
||||
|
||||
setLabel(label: string): void {
|
||||
if (this._label !== label) {
|
||||
this._label = label;
|
||||
this._onDidGroupChange.fire({ kind: GroupChangeKind.GROUP_LABEL });
|
||||
get isEmpty(): boolean {
|
||||
return this._group.count === 0;
|
||||
}
|
||||
|
||||
get isMinimized(): boolean {
|
||||
if (!this.dimension) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.dimension.width === this.minimumWidth || this.dimension.height === this.minimumHeight;
|
||||
}
|
||||
|
||||
notifyIndexChanged(newIndex: number): void {
|
||||
if (this._index !== newIndex) {
|
||||
this._index = newIndex;
|
||||
this._onDidGroupChange.fire({ kind: GroupChangeKind.GROUP_INDEX });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -685,10 +714,6 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
this._onDidGroupChange.fire({ kind: GroupChangeKind.GROUP_ACTIVE });
|
||||
}
|
||||
|
||||
isEmpty(): boolean {
|
||||
return this._group.count === 0;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region IEditorGroup
|
||||
@@ -1213,7 +1238,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
//#region closeEditors()
|
||||
|
||||
async closeEditors(args: EditorInput[] | ICloseEditorsFilter, options?: ICloseEditorOptions): Promise<void> {
|
||||
if (this.isEmpty()) {
|
||||
if (this.isEmpty) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1285,7 +1310,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
//#region closeAllEditors()
|
||||
|
||||
async closeAllEditors(): Promise<void> {
|
||||
if (this.isEmpty()) {
|
||||
if (this.isEmpty) {
|
||||
|
||||
// If the group is empty and the request is to close all editors, we still close
|
||||
// the editor group is the related setting to close empty groups is enabled for
|
||||
@@ -1397,7 +1422,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
//#region Themable
|
||||
|
||||
protected updateStyles(): void {
|
||||
const isEmpty = this.isEmpty();
|
||||
const isEmpty = this.isEmpty;
|
||||
|
||||
// Container
|
||||
if (isEmpty) {
|
||||
@@ -1446,10 +1471,14 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
this.editorContainer.style.height = `calc(100% - ${this.titleAreaControl.getPreferredHeight()}px)`;
|
||||
|
||||
// Forward to controls
|
||||
this.titleAreaControl.layout(new Dimension(this.dimension.width, this.titleAreaControl.getPreferredHeight()));
|
||||
this.layoutTitleAreaControl();
|
||||
this.editorControl.layout(new Dimension(this.dimension.width, this.dimension.height - this.titleAreaControl.getPreferredHeight()));
|
||||
}
|
||||
|
||||
private layoutTitleAreaControl(): void {
|
||||
this.titleAreaControl.layout(new Dimension(this.dimension.width, this.titleAreaControl.getPreferredHeight()));
|
||||
}
|
||||
|
||||
relayout(): void {
|
||||
if (this.dimension) {
|
||||
const { width, height } = this.dimension;
|
||||
@@ -1469,7 +1498,6 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
this._onWillDispose.fire();
|
||||
|
||||
this.titleAreaControl.dispose();
|
||||
// this.editorControl = null;
|
||||
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@ import { assign } from 'vs/base/common/objects';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { ISerializedEditorGroup, isSerializedEditorGroup } from 'vs/workbench/common/editor/editorGroup';
|
||||
import { EditorDropTarget } from 'vs/workbench/browser/parts/editor/editorDropTarget';
|
||||
import { localize } from 'vs/nls';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
import { CenteredViewLayout } from 'vs/base/browser/ui/centered/centeredViewLayout';
|
||||
import { onUnexpectedError } from 'vs/base/common/errors';
|
||||
@@ -82,7 +81,7 @@ class GridWidgetView<T extends IView> implements IView {
|
||||
|
||||
export class EditorPart extends Part implements IEditorGroupsService, IEditorGroupsAccessor {
|
||||
|
||||
_serviceBrand: ServiceIdentifier<any>;
|
||||
_serviceBrand!: ServiceIdentifier<any>;
|
||||
|
||||
private static readonly EDITOR_PART_UI_STATE_STORAGE_KEY = 'editorpart.state';
|
||||
private static readonly EDITOR_PART_CENTERED_VIEW_STORAGE_KEY = 'editorpart.centeredview';
|
||||
@@ -95,6 +94,9 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro
|
||||
private readonly _onDidActiveGroupChange: Emitter<IEditorGroupView> = this._register(new Emitter<IEditorGroupView>());
|
||||
readonly onDidActiveGroupChange: Event<IEditorGroupView> = this._onDidActiveGroupChange.event;
|
||||
|
||||
private readonly _onDidGroupIndexChange: Emitter<IEditorGroupView> = this._register(new Emitter<IEditorGroupView>());
|
||||
readonly onDidGroupIndexChange: Event<IEditorGroupView> = this._onDidGroupIndexChange.event;
|
||||
|
||||
private readonly _onDidActivateGroup: Emitter<IEditorGroupView> = this._register(new Emitter<IEditorGroupView>());
|
||||
readonly onDidActivateGroup: Event<IEditorGroupView> = this._onDidActivateGroup.event;
|
||||
|
||||
@@ -344,15 +346,36 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro
|
||||
return; // we have not been created yet
|
||||
}
|
||||
|
||||
// Even all group sizes
|
||||
if (arrangement === GroupsArrangement.EVEN) {
|
||||
this.gridWidget.distributeViewSizes();
|
||||
switch (arrangement) {
|
||||
case GroupsArrangement.EVEN:
|
||||
this.gridWidget.distributeViewSizes();
|
||||
break;
|
||||
case GroupsArrangement.MINIMIZE_OTHERS:
|
||||
this.gridWidget.maximizeViewSize(this.activeGroup);
|
||||
break;
|
||||
case GroupsArrangement.TOGGLE:
|
||||
if (this.isGroupMaximized(this.activeGroup)) {
|
||||
this.arrangeGroups(GroupsArrangement.EVEN);
|
||||
} else {
|
||||
this.arrangeGroups(GroupsArrangement.MINIMIZE_OTHERS);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private isGroupMaximized(targetGroup: IEditorGroupView): boolean {
|
||||
for (const group of this.groups) {
|
||||
if (group === targetGroup) {
|
||||
continue; // ignore target group
|
||||
}
|
||||
|
||||
if (!group.isMinimized) {
|
||||
return false; // target cannot be maximized if one group is not minimized
|
||||
}
|
||||
}
|
||||
|
||||
// Maximize the current active group
|
||||
else {
|
||||
this.gridWidget.maximizeViewSize(this.activeGroup);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
setGroupOrientation(orientation: GroupOrientation): void {
|
||||
@@ -424,8 +447,8 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro
|
||||
}
|
||||
});
|
||||
|
||||
// Update labels
|
||||
this.updateGroupLabels();
|
||||
// Notify group index change given layout has changed
|
||||
this.notifyGroupIndexChange();
|
||||
|
||||
// Restore focus as needed
|
||||
if (restoreFocus) {
|
||||
@@ -484,25 +507,22 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro
|
||||
// Event
|
||||
this._onDidAddGroup.fire(newGroupView);
|
||||
|
||||
// Update labels
|
||||
this.updateGroupLabels();
|
||||
// Notify group index change given a new group was added
|
||||
this.notifyGroupIndexChange();
|
||||
|
||||
return newGroupView;
|
||||
}
|
||||
|
||||
private doCreateGroupView(from?: IEditorGroupView | ISerializedEditorGroup | null): IEditorGroupView {
|
||||
|
||||
// Label: just use the number of existing groups as label
|
||||
const label = this.getGroupLabel(this.count + 1);
|
||||
|
||||
// Create group view
|
||||
let groupView: IEditorGroupView;
|
||||
if (from instanceof EditorGroupView) {
|
||||
groupView = EditorGroupView.createCopy(from, this, label, this.instantiationService);
|
||||
groupView = EditorGroupView.createCopy(from, this, this.count, this.instantiationService);
|
||||
} else if (isSerializedEditorGroup(from)) {
|
||||
groupView = EditorGroupView.createFromSerialized(from, this, label, this.instantiationService);
|
||||
groupView = EditorGroupView.createFromSerialized(from, this, this.count, this.instantiationService);
|
||||
} else {
|
||||
groupView = EditorGroupView.createNew(this, label, this.instantiationService);
|
||||
groupView = EditorGroupView.createNew(this, this.count, this.instantiationService);
|
||||
}
|
||||
|
||||
// Keep in map
|
||||
@@ -516,8 +536,13 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro
|
||||
|
||||
// Track editor change
|
||||
groupDisposables.add(groupView.onDidGroupChange(e => {
|
||||
if (e.kind === GroupChangeKind.EDITOR_ACTIVE) {
|
||||
this.updateContainer();
|
||||
switch (e.kind) {
|
||||
case GroupChangeKind.EDITOR_ACTIVE:
|
||||
this.updateContainer();
|
||||
break;
|
||||
case GroupChangeKind.GROUP_INDEX:
|
||||
this._onDidGroupIndexChange.fire(groupView);
|
||||
break;
|
||||
}
|
||||
}));
|
||||
|
||||
@@ -600,7 +625,7 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro
|
||||
}
|
||||
|
||||
// Remove empty group
|
||||
if (groupView.isEmpty()) {
|
||||
if (groupView.isEmpty) {
|
||||
return this.doRemoveEmptyGroup(groupView);
|
||||
}
|
||||
|
||||
@@ -643,8 +668,8 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro
|
||||
this._activeGroup.focus();
|
||||
}
|
||||
|
||||
// Update labels
|
||||
this.updateGroupLabels();
|
||||
// Notify group index change given a group was removed
|
||||
this.notifyGroupIndexChange();
|
||||
|
||||
// Update container
|
||||
this.updateContainer();
|
||||
@@ -675,6 +700,9 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro
|
||||
// Event
|
||||
this._onDidMoveGroup.fire(sourceView);
|
||||
|
||||
// Notify group index change given a group was moved
|
||||
this.notifyGroupIndexChange();
|
||||
|
||||
return sourceView;
|
||||
}
|
||||
|
||||
@@ -715,7 +743,7 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro
|
||||
});
|
||||
|
||||
// Remove source if the view is now empty and not already removed
|
||||
if (sourceView.isEmpty() && !sourceView.disposed /* could have been disposed already via workbench.editor.closeEmptyGroups setting */) {
|
||||
if (sourceView.isEmpty && !sourceView.disposed /* could have been disposed already via workbench.editor.closeEmptyGroups setting */) {
|
||||
this.removeGroup(sourceView);
|
||||
}
|
||||
|
||||
@@ -784,6 +812,7 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro
|
||||
|
||||
centerLayout(active: boolean): void {
|
||||
this.centeredLayoutWidget.activate(active);
|
||||
|
||||
this._activeGroup.focus();
|
||||
}
|
||||
|
||||
@@ -813,6 +842,9 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro
|
||||
|
||||
// Update container
|
||||
this.updateContainer();
|
||||
|
||||
// Notify group index change we created the entire grid
|
||||
this.notifyGroupIndexChange();
|
||||
}
|
||||
|
||||
private doCreateGridControlWithPreviousState(): boolean {
|
||||
@@ -906,26 +938,15 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro
|
||||
}
|
||||
|
||||
private updateContainer(): void {
|
||||
toggleClass(this.container, 'empty', this.isEmpty());
|
||||
toggleClass(this.container, 'empty', this.isEmpty);
|
||||
}
|
||||
|
||||
private updateGroupLabels(): void {
|
||||
|
||||
// Since our labels are created using the index of the
|
||||
// group, adding/removing a group might produce gaps.
|
||||
// So we iterate over all groups and reassign the label
|
||||
// based on the index.
|
||||
this.getGroups(GroupsOrder.GRID_APPEARANCE).forEach((group, index) => {
|
||||
group.setLabel(this.getGroupLabel(index + 1));
|
||||
});
|
||||
private notifyGroupIndexChange(): void {
|
||||
this.getGroups(GroupsOrder.GRID_APPEARANCE).forEach((group, index) => group.notifyIndexChanged(index));
|
||||
}
|
||||
|
||||
private getGroupLabel(index: number): string {
|
||||
return localize('groupLabel', "Group {0}", index);
|
||||
}
|
||||
|
||||
private isEmpty(): boolean {
|
||||
return this.groupViews.size === 1 && this._activeGroup.isEmpty();
|
||||
private get isEmpty(): boolean {
|
||||
return this.groupViews.size === 1 && this._activeGroup.isEmpty;
|
||||
}
|
||||
|
||||
layout(width: number, height: number): void {
|
||||
@@ -957,7 +978,7 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro
|
||||
mostRecentActiveGroups: this.mostRecentActiveGroups
|
||||
};
|
||||
|
||||
if (this.isEmpty()) {
|
||||
if (this.isEmpty) {
|
||||
delete this.workspaceMemento[EditorPart.EDITOR_PART_UI_STATE_STORAGE_KEY];
|
||||
} else {
|
||||
this.workspaceMemento[EditorPart.EDITOR_PART_UI_STATE_STORAGE_KEY] = uiState;
|
||||
|
||||
@@ -285,4 +285,4 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => {
|
||||
if (notificationBorderColor) {
|
||||
collector.addRule(`.monaco-workbench > .notifications-center .notifications-list-container .monaco-list-row[data-last-element="false"] > .notification-list-item { border-bottom: 1px solid ${notificationBorderColor}; }`);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -11,12 +11,12 @@ import { localize } from 'vs/nls';
|
||||
|
||||
export class NotificationsStatus extends Disposable {
|
||||
|
||||
private notificationsCenterStatusItem: IStatusbarEntryAccessor;
|
||||
private notificationsCenterStatusItem: IStatusbarEntryAccessor | undefined;
|
||||
private currentNotifications = new Set<INotificationViewItem>();
|
||||
|
||||
private currentStatusMessage: [IStatusMessageViewItem, IDisposable] | undefined;
|
||||
|
||||
private isNotificationsCenterVisible: boolean;
|
||||
private isNotificationsCenterVisible: boolean | undefined;
|
||||
|
||||
constructor(
|
||||
private model: INotificationsModel,
|
||||
@@ -172,4 +172,4 @@ export class NotificationsStatus extends Disposable {
|
||||
// Remember as current status message
|
||||
this.currentStatusMessage = [item, statusMessageDispose];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ export class NotificationsListDelegate implements IListVirtualDelegate<INotifica
|
||||
}
|
||||
|
||||
// Last row: source and buttons if we have any
|
||||
if (notification.source || isNonEmptyArray(notification.actions.primary)) {
|
||||
if (notification.source || isNonEmptyArray(notification.actions && notification.actions.primary)) {
|
||||
expandedHeight += NotificationsListDelegate.ROW_HEIGHT;
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ export class NotificationsListDelegate implements IListVirtualDelegate<INotifica
|
||||
if (notification.canCollapse) {
|
||||
actions++; // expand/collapse
|
||||
}
|
||||
if (isNonEmptyArray(notification.actions.secondary)) {
|
||||
if (isNonEmptyArray(notification.actions && notification.actions.secondary)) {
|
||||
actions++; // secondary actions
|
||||
}
|
||||
this.offsetHelper.style.width = `calc(100% - ${10 /* padding */ + 24 /* severity icon */ + (actions * 24) /* 24px per action */}px)`;
|
||||
@@ -392,8 +392,9 @@ export class NotificationTemplateRenderer extends Disposable {
|
||||
const actions: IAction[] = [];
|
||||
|
||||
// Secondary Actions
|
||||
if (isNonEmptyArray(notification.actions.secondary)) {
|
||||
const configureNotificationAction = this.instantiationService.createInstance(ConfigureNotificationAction, ConfigureNotificationAction.ID, ConfigureNotificationAction.LABEL, notification.actions.secondary);
|
||||
const secondaryActions = notification.actions ? notification.actions.secondary : undefined;
|
||||
if (isNonEmptyArray(secondaryActions)) {
|
||||
const configureNotificationAction = this.instantiationService.createInstance(ConfigureNotificationAction, ConfigureNotificationAction.ID, ConfigureNotificationAction.LABEL, secondaryActions);
|
||||
actions.push(configureNotificationAction);
|
||||
this.inputDisposables.add(configureNotificationAction);
|
||||
}
|
||||
@@ -435,10 +436,11 @@ export class NotificationTemplateRenderer extends Disposable {
|
||||
private renderButtons(notification: INotificationViewItem): void {
|
||||
clearNode(this.template.buttonsContainer);
|
||||
|
||||
if (notification.expanded && notification.actions.primary) {
|
||||
const buttonGroup = new ButtonGroup(this.template.buttonsContainer, notification.actions.primary.length, { title: true /* assign titles to buttons in case they overflow */ });
|
||||
const primaryActions = notification.actions ? notification.actions.primary : undefined;
|
||||
if (notification.expanded && isNonEmptyArray(primaryActions)) {
|
||||
const buttonGroup = new ButtonGroup(this.template.buttonsContainer, primaryActions.length, { title: true /* assign titles to buttons in case they overflow */ });
|
||||
buttonGroup.buttons.forEach((button, index) => {
|
||||
const action = notification.actions.primary![index];
|
||||
const action = primaryActions[index];
|
||||
button.label = action.label;
|
||||
|
||||
this.inputDisposables.add(button.onDidClick(e => {
|
||||
|
||||
@@ -25,11 +25,19 @@
|
||||
border-top-style: solid;
|
||||
}
|
||||
|
||||
.monaco-workbench.noeditorarea .part.panel.bottom .title {
|
||||
border-top-width: 0; /* no border when editor area is hiden */
|
||||
}
|
||||
|
||||
.monaco-workbench .part.panel.right {
|
||||
border-left-width: 1px;
|
||||
border-left-style: solid;
|
||||
}
|
||||
|
||||
.monaco-workbench.noeditorarea .part.panel.right {
|
||||
border-left-width: 0; /* no border when editor area is hiden */
|
||||
}
|
||||
|
||||
.monaco-workbench .part.panel > .title > .title-actions .monaco-action-bar .action-item .action-label {
|
||||
outline-offset: -2px;
|
||||
}
|
||||
@@ -181,4 +189,4 @@
|
||||
|
||||
.hc-black .monaco-workbench .panel.right .minimize-panel-action {
|
||||
background-image: url('chevron-right-hc.svg');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
private static readonly PINNED_PANELS = 'workbench.panel.pinnedPanels';
|
||||
private static readonly MIN_COMPOSITE_BAR_WIDTH = 50;
|
||||
|
||||
_serviceBrand: ServiceIdentifier<any>;
|
||||
_serviceBrand!: ServiceIdentifier<any>;
|
||||
|
||||
//#region IView
|
||||
|
||||
@@ -83,8 +83,8 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
private compositeBar: CompositeBar;
|
||||
private compositeActions: Map<string, { activityAction: PanelActivityAction, pinnedAction: ToggleCompositePinnedAction }> = new Map();
|
||||
|
||||
private blockOpeningPanel: boolean;
|
||||
private _contentDimension: Dimension;
|
||||
private blockOpeningPanel = false;
|
||||
private _contentDimension: Dimension | undefined;
|
||||
|
||||
constructor(
|
||||
@INotificationService notificationService: INotificationService,
|
||||
@@ -367,7 +367,7 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
private onDidStorageChange(e: IWorkspaceStorageChangeEvent): void {
|
||||
if (e.key === PanelPart.PINNED_PANELS && e.scope === StorageScope.GLOBAL
|
||||
&& this.cachedPanelsValue !== this.getStoredCachedPanelsValue() /* This checks if current window changed the value or not */) {
|
||||
this._cachedPanelsValue = null;
|
||||
this._cachedPanelsValue = undefined;
|
||||
const newCompositeItems: ICompositeBarItem[] = [];
|
||||
const compositeItems = this.compositeBar.getCompositeBarItems();
|
||||
const cachedPanels = this.getCachedPanels();
|
||||
@@ -422,7 +422,7 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
return cachedPanels;
|
||||
}
|
||||
|
||||
private _cachedPanelsValue: string | null;
|
||||
private _cachedPanelsValue: string | undefined;
|
||||
private get cachedPanelsValue(): string {
|
||||
if (!this._cachedPanelsValue) {
|
||||
this._cachedPanelsValue = this.getStoredCachedPanelsValue();
|
||||
|
||||
@@ -880,7 +880,7 @@ class InputBox extends QuickInput implements IInputBox {
|
||||
|
||||
export class QuickInputService extends Component implements IQuickInputService {
|
||||
|
||||
public _serviceBrand: ServiceIdentifier<any>;
|
||||
public _serviceBrand!: ServiceIdentifier<any>;
|
||||
|
||||
private static readonly ID = 'workbench.component.quickinput';
|
||||
private static readonly MAX_WIDTH = 600; // Max total width of quick open widget
|
||||
|
||||
@@ -114,7 +114,7 @@ class ListElementRenderer implements IListRenderer<ListElement, IListElementTemp
|
||||
const row2 = dom.append(rows, $('.quick-input-list-row'));
|
||||
|
||||
// Label
|
||||
data.label = new IconLabel(row1, { supportHighlights: true, supportDescriptionHighlights: true });
|
||||
data.label = new IconLabel(row1, { supportHighlights: true, supportDescriptionHighlights: true, supportOcticons: true });
|
||||
|
||||
// Detail
|
||||
const detailContainer = dom.append(row2, $('.quick-input-list-label-meta'));
|
||||
|
||||
@@ -61,7 +61,7 @@ export class QuickOpenController extends Component implements IQuickOpenService
|
||||
private static readonly MAX_SHORT_RESPONSE_TIME = 500;
|
||||
private static readonly ID = 'workbench.component.quickopen';
|
||||
|
||||
_serviceBrand: ServiceIdentifier<any>;
|
||||
_serviceBrand!: ServiceIdentifier<any>;
|
||||
|
||||
private readonly _onShow: Emitter<void> = this._register(new Emitter<void>());
|
||||
readonly onShow: Event<void> = this._onShow.event;
|
||||
@@ -861,4 +861,4 @@ export class RemoveFromEditorHistoryAction extends Action {
|
||||
}
|
||||
}
|
||||
|
||||
registerSingleton(IQuickOpenService, QuickOpenController, true);
|
||||
registerSingleton(IQuickOpenService, QuickOpenController, true);
|
||||
|
||||
@@ -31,10 +31,11 @@ import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/c
|
||||
import { AnchorAlignment } from 'vs/base/browser/ui/contextview/contextview';
|
||||
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
||||
import { LayoutPriority } from 'vs/base/browser/ui/grid/grid';
|
||||
|
||||
export class SidebarPart extends CompositePart<Viewlet> implements IViewletService {
|
||||
|
||||
_serviceBrand: ServiceIdentifier<any>;
|
||||
_serviceBrand!: ServiceIdentifier<any>;
|
||||
|
||||
static readonly activeViewletSettingsKey = 'workbench.sidebar.activeviewletid';
|
||||
|
||||
@@ -45,6 +46,8 @@ export class SidebarPart extends CompositePart<Viewlet> implements IViewletServi
|
||||
readonly minimumHeight: number = 0;
|
||||
readonly maximumHeight: number = Number.POSITIVE_INFINITY;
|
||||
|
||||
readonly priority: LayoutPriority = LayoutPriority.Low;
|
||||
|
||||
readonly snap = true;
|
||||
|
||||
get preferredWidth(): number | undefined {
|
||||
@@ -79,7 +82,7 @@ export class SidebarPart extends CompositePart<Viewlet> implements IViewletServi
|
||||
private viewletRegistry: ViewletRegistry;
|
||||
private sideBarFocusContextKey: IContextKey<boolean>;
|
||||
private activeViewletContextKey: IContextKey<string>;
|
||||
private blockOpeningViewlet: boolean;
|
||||
private blockOpeningViewlet = false;
|
||||
|
||||
constructor(
|
||||
@INotificationService notificationService: INotificationService,
|
||||
|
||||
@@ -323,7 +323,7 @@ class HideStatusbarEntryAction extends Action {
|
||||
|
||||
export class StatusbarPart extends Part implements IStatusbarService {
|
||||
|
||||
_serviceBrand: ServiceIdentifier<IStatusbarService>;
|
||||
_serviceBrand!: ServiceIdentifier<IStatusbarService>;
|
||||
|
||||
//#region IView
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ export class TitlebarPart extends Part implements ITitleService {
|
||||
private _onMenubarVisibilityChange = this._register(new Emitter<boolean>());
|
||||
readonly onMenubarVisibilityChange: Event<boolean> = this._onMenubarVisibilityChange.event;
|
||||
|
||||
_serviceBrand: ServiceIdentifier<any>;
|
||||
_serviceBrand!: ServiceIdentifier<any>;
|
||||
|
||||
private title: HTMLElement;
|
||||
private dragRegion: HTMLElement;
|
||||
@@ -639,4 +639,4 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => {
|
||||
}
|
||||
});
|
||||
|
||||
registerSingleton(ITitleService, TitlebarPart);
|
||||
registerSingleton(ITitleService, TitlebarPart);
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import 'vs/css!./media/views';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { IDisposable, Disposable, toDisposable, DisposableStore, MutableDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IDisposable, Disposable, toDisposable, MutableDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IAction, IActionViewItem, ActionRunner, Action } from 'vs/base/common/actions';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
@@ -33,18 +33,14 @@ import { ViewletPanel, IViewletPanelOptions } from 'vs/workbench/browser/parts/v
|
||||
import { localize } from 'vs/nls';
|
||||
import { timeout } from 'vs/base/common/async';
|
||||
import { editorFindMatchHighlight, editorFindMatchHighlightBorder, textLinkForeground, textCodeBlockBackground, focusBorder } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { IMarkdownString } from 'vs/base/common/htmlContent';
|
||||
import { isString } from 'vs/base/common/types';
|
||||
import { renderMarkdown, RenderOptions } from 'vs/base/browser/htmlContentRenderer';
|
||||
import { onUnexpectedError } from 'vs/base/common/errors';
|
||||
import { IOpenerService } from 'vs/platform/opener/common/opener';
|
||||
import { IMarkdownRenderResult } from 'vs/editor/contrib/markdown/markdownRenderer';
|
||||
import { ILabelService } from 'vs/platform/label/common/label';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { IListVirtualDelegate, IIdentityProvider } from 'vs/base/browser/ui/list/list';
|
||||
import { ITreeRenderer, ITreeNode, IAsyncDataSource, ITreeContextMenuEvent } from 'vs/base/browser/ui/tree/tree';
|
||||
import { FuzzyScore, createMatches } from 'vs/base/common/filters';
|
||||
import { CollapseAllAction } from 'vs/base/browser/ui/tree/treeDefaults';
|
||||
import { isFalsyOrWhitespace } from 'vs/base/common/strings';
|
||||
|
||||
export class CustomTreeViewPanel extends ViewletPanel {
|
||||
|
||||
@@ -167,7 +163,7 @@ export class CustomTreeView extends Disposable implements ITreeView {
|
||||
private focused: boolean = false;
|
||||
private domNode: HTMLElement;
|
||||
private treeContainer: HTMLElement;
|
||||
private _messageValue: string | IMarkdownString | undefined;
|
||||
private _messageValue: string | undefined;
|
||||
private messageElement: HTMLDivElement;
|
||||
private tree: WorkbenchAsyncDataTree<ITreeItem, ITreeItem, FuzzyScore>;
|
||||
private treeLabels: ResourceLabels;
|
||||
@@ -175,9 +171,6 @@ export class CustomTreeView extends Disposable implements ITreeView {
|
||||
private elementsToRefresh: ITreeItem[] = [];
|
||||
private menus: TitleMenus;
|
||||
|
||||
private markdownRenderer: MarkdownRenderer;
|
||||
private markdownResult: IMarkdownRenderResult | null;
|
||||
|
||||
private readonly _onDidExpandItem: Emitter<ITreeItem> = this._register(new Emitter<ITreeItem>());
|
||||
readonly onDidExpandItem: Event<ITreeItem> = this._onDidExpandItem.event;
|
||||
|
||||
@@ -217,12 +210,6 @@ export class CustomTreeView extends Disposable implements ITreeView {
|
||||
this.doRefresh([this.root]); /** soft refresh **/
|
||||
}
|
||||
}));
|
||||
this.markdownRenderer = instantiationService.createInstance(MarkdownRenderer);
|
||||
this._register(toDisposable(() => {
|
||||
if (this.markdownResult) {
|
||||
this.markdownResult.dispose();
|
||||
}
|
||||
}));
|
||||
this._register(Registry.as<IViewsRegistry>(Extensions.ViewsRegistry).onDidChangeContainer(({ views, from, to }) => {
|
||||
if (from === this.viewContainer && views.some(v => v.id === this.id)) {
|
||||
this.viewContainer = to;
|
||||
@@ -256,12 +243,12 @@ export class CustomTreeView extends Disposable implements ITreeView {
|
||||
}
|
||||
}
|
||||
|
||||
private _message: string | IMarkdownString | undefined;
|
||||
get message(): string | IMarkdownString | undefined {
|
||||
private _message: string | undefined;
|
||||
get message(): string | undefined {
|
||||
return this._message;
|
||||
}
|
||||
|
||||
set message(message: string | IMarkdownString | undefined) {
|
||||
set message(message: string | undefined) {
|
||||
this._message = message;
|
||||
this.updateMessage();
|
||||
}
|
||||
@@ -470,16 +457,13 @@ export class CustomTreeView extends Disposable implements ITreeView {
|
||||
this.updateContentAreas();
|
||||
}
|
||||
|
||||
private showMessage(message: string | IMarkdownString): void {
|
||||
private showMessage(message: string): void {
|
||||
DOM.removeClass(this.messageElement, 'hide');
|
||||
if (this._messageValue !== message) {
|
||||
this.resetMessageElement();
|
||||
this._messageValue = message;
|
||||
if (isString(this._messageValue)) {
|
||||
if (!isFalsyOrWhitespace(this._message)) {
|
||||
this.messageElement.textContent = this._messageValue;
|
||||
} else {
|
||||
this.markdownResult = this.markdownRenderer.render(this._messageValue);
|
||||
DOM.append(this.messageElement, this.markdownResult.element);
|
||||
}
|
||||
this.layout(this._height, this._width);
|
||||
}
|
||||
@@ -492,10 +476,6 @@ export class CustomTreeView extends Disposable implements ITreeView {
|
||||
}
|
||||
|
||||
private resetMessageElement(): void {
|
||||
if (this.markdownResult) {
|
||||
this.markdownResult.dispose();
|
||||
this.markdownResult = null;
|
||||
}
|
||||
DOM.clearNode(this.messageElement);
|
||||
}
|
||||
|
||||
@@ -597,8 +577,16 @@ export class CustomTreeView extends Disposable implements ITreeView {
|
||||
private async doRefresh(elements: ITreeItem[]): Promise<void> {
|
||||
if (this.tree) {
|
||||
this.refreshing = true;
|
||||
await Promise.all(elements.map(element => this.tree.updateChildren(element, true)));
|
||||
elements.map(element => this.tree.rerender(element));
|
||||
const parents: Set<ITreeItem> = new Set<ITreeItem>();
|
||||
elements.forEach(element => {
|
||||
if (element !== this.root) {
|
||||
const parent = this.tree.getParentElement(element);
|
||||
parents.add(parent);
|
||||
} else {
|
||||
parents.add(element);
|
||||
}
|
||||
});
|
||||
await Promise.all(Array.from(parents.values()).map(element => this.tree.updateChildren(element, true)));
|
||||
this.refreshing = false;
|
||||
this.updateContentAreas();
|
||||
if (this.focused) {
|
||||
@@ -718,7 +706,7 @@ class TreeRenderer extends Disposable implements ITreeRenderer<ITreeItem, FuzzyS
|
||||
|
||||
const icon = DOM.append(container, DOM.$('.custom-view-tree-node-item-icon'));
|
||||
|
||||
const resourceLabel = this.labels.create(container, { supportHighlights: true, donotSupportOcticons: true });
|
||||
const resourceLabel = this.labels.create(container, { supportHighlights: true });
|
||||
const actionsContainer = DOM.append(resourceLabel.element, DOM.$('.actions'));
|
||||
const actionBar = new ActionBar(actionsContainer, {
|
||||
actionViewItemProvider: this.actionViewItemProvider
|
||||
@@ -885,38 +873,3 @@ class TreeMenus extends Disposable implements IDisposable {
|
||||
}
|
||||
}
|
||||
|
||||
class MarkdownRenderer {
|
||||
|
||||
constructor(
|
||||
@IOpenerService private readonly _openerService: IOpenerService
|
||||
) {
|
||||
}
|
||||
|
||||
private getOptions(disposeables: DisposableStore): RenderOptions {
|
||||
return {
|
||||
actionHandler: {
|
||||
callback: (content) => {
|
||||
let uri: URI | undefined;
|
||||
try {
|
||||
uri = URI.parse(content);
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
if (uri && this._openerService) {
|
||||
this._openerService.open(uri).catch(onUnexpectedError);
|
||||
}
|
||||
},
|
||||
disposeables
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
render(markdown: IMarkdownString): IMarkdownRenderResult {
|
||||
const disposeables = new DisposableStore();
|
||||
const element: HTMLElement = markdown ? renderMarkdown(markdown, this.getOptions(disposeables)) : document.createElement('span');
|
||||
return {
|
||||
element,
|
||||
dispose: () => disposeables.dispose()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -626,7 +626,7 @@ export class PersistentContributableViewsModel extends ContributableViewsModel {
|
||||
|
||||
export class ViewsService extends Disposable implements IViewsService {
|
||||
|
||||
_serviceBrand: ServiceIdentifier<any>;
|
||||
_serviceBrand!: ServiceIdentifier<any>;
|
||||
|
||||
private readonly viewDescriptorCollections: Map<ViewContainer, { viewDescriptorCollection: IViewDescriptorCollection, disposable: IDisposable }>;
|
||||
private readonly viewDisposable: Map<IViewDescriptor, IDisposable>;
|
||||
|
||||
@@ -76,7 +76,7 @@ export const Extensions = {
|
||||
};
|
||||
|
||||
export class ViewletRegistry extends CompositeRegistry<Viewlet> {
|
||||
private defaultViewletId: string;
|
||||
private defaultViewletId!: string;
|
||||
|
||||
/**
|
||||
* Registers a viewlet to the platform.
|
||||
|
||||
@@ -40,14 +40,10 @@ import { joinPath } from 'vs/base/common/resources';
|
||||
import { BrowserStorageService } from 'vs/platform/storage/browser/storageService';
|
||||
import { IStorageService } from 'vs/platform/storage/common/storage';
|
||||
import { getThemeTypeSelector, DARK, HIGH_CONTRAST, LIGHT } from 'vs/platform/theme/common/themeService';
|
||||
import { IRequestService } from 'vs/platform/request/common/request';
|
||||
import { RequestService } from 'vs/workbench/services/request/browser/requestService';
|
||||
import { InMemoryUserDataProvider } from 'vs/workbench/services/userData/common/inMemoryUserDataProvider';
|
||||
|
||||
class CodeRendererMain extends Disposable {
|
||||
|
||||
private workbench: Workbench;
|
||||
|
||||
constructor(
|
||||
private readonly domElement: HTMLElement,
|
||||
private readonly configuration: IWorkbenchConstructionOptions
|
||||
@@ -65,24 +61,30 @@ class CodeRendererMain extends Disposable {
|
||||
this.restoreBaseTheme();
|
||||
|
||||
// Create Workbench
|
||||
this.workbench = new Workbench(
|
||||
const workbench = new Workbench(
|
||||
this.domElement,
|
||||
services.serviceCollection,
|
||||
services.logService
|
||||
);
|
||||
|
||||
// Layout
|
||||
this._register(addDisposableListener(window, EventType.RESIZE, () => this.workbench.layout()));
|
||||
this._register(addDisposableListener(window, EventType.RESIZE, () => workbench.layout()));
|
||||
|
||||
// Workbench Lifecycle
|
||||
this._register(this.workbench.onShutdown(() => this.dispose()));
|
||||
this._register(this.workbench.onWillShutdown(() => {
|
||||
this._register(workbench.onBeforeShutdown(event => {
|
||||
if (services.storageService.hasPendingUpdate) {
|
||||
console.warn('Unload prevented: pending storage update');
|
||||
event.veto(true); // prevent data loss from pending storage update
|
||||
}
|
||||
}));
|
||||
this._register(workbench.onWillShutdown(() => {
|
||||
services.storageService.close();
|
||||
this.saveBaseTheme();
|
||||
}));
|
||||
this._register(workbench.onShutdown(() => this.dispose()));
|
||||
|
||||
// Startup
|
||||
this.workbench.startup();
|
||||
workbench.startup();
|
||||
}
|
||||
|
||||
private restoreBaseTheme(): void {
|
||||
@@ -105,7 +107,7 @@ class CodeRendererMain extends Disposable {
|
||||
|
||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
// NOTE: DO NOT ADD ANY OTHER SERVICE INTO THE COLLECTION HERE.
|
||||
// CONTRIBUTE IT VIA WORKBENCH.MAIN.TS AND registerSingleton().
|
||||
// CONTRIBUTE IT VIA WORKBENCH.WEB.MAIN.TS AND registerSingleton().
|
||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
// Log
|
||||
@@ -166,7 +168,7 @@ class CodeRendererMain extends Disposable {
|
||||
// User Data Provider
|
||||
fileService.registerProvider(Schemas.userData, userDataProvider);
|
||||
|
||||
const [configurationService, storageService] = await Promise.all([
|
||||
const services = await Promise.all([
|
||||
this.createWorkspaceService(payload, environmentService, fileService, remoteAgentService, logService).then(service => {
|
||||
|
||||
// Workspace
|
||||
@@ -187,10 +189,7 @@ class CodeRendererMain extends Disposable {
|
||||
})
|
||||
]);
|
||||
|
||||
// Request Service
|
||||
serviceCollection.set(IRequestService, new RequestService(this.configuration.requestHandler, remoteAgentService, configurationService, logService));
|
||||
|
||||
return { serviceCollection, logService, storageService };
|
||||
return { serviceCollection, logService, storageService: services[1] };
|
||||
}
|
||||
|
||||
private async createStorageService(payload: IWorkspaceInitializationPayload, environmentService: IWorkbenchEnvironmentService, fileService: IFileService, logService: ILogService): Promise<BrowserStorageService> {
|
||||
|
||||
@@ -22,7 +22,6 @@ import { IRecentlyOpened, IRecent, isRecentFile, isRecentFolder } from 'vs/platf
|
||||
import { ISerializableCommandAction } from 'vs/platform/actions/common/actions';
|
||||
import { IWorkspaceEditingService } from 'vs/workbench/services/workspace/common/workspaceEditing';
|
||||
import { ITunnelService } from 'vs/platform/remote/common/tunnel';
|
||||
import { IExtensionHostDebugService } from 'vs/platform/debug/common/extensionHostDebug';
|
||||
// tslint:disable-next-line: import-patterns
|
||||
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
|
||||
import { addDisposableListener, EventType } from 'vs/base/browser/dom';
|
||||
@@ -30,14 +29,17 @@ import { IEditorService, IResourceEditor } from 'vs/workbench/services/editor/co
|
||||
import { pathsToEditors } from 'vs/workbench/common/editor';
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { ParsedArgs, IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { ParsedArgs } from 'vs/platform/environment/common/environment';
|
||||
import { IProcessEnvironment } from 'vs/base/common/platform';
|
||||
import { toStoreData, restoreRecentlyOpened } from 'vs/platform/history/common/historyStorage';
|
||||
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
|
||||
// tslint:disable-next-line: import-patterns
|
||||
import { IExperimentService, IExperiment, ExperimentActionType, ExperimentState } from 'vs/workbench/contrib/experiments/common/experimentService';
|
||||
import { ExtensionHostDebugChannelClient, ExtensionHostDebugBroadcastChannel } from 'vs/platform/debug/common/extensionHostDebugIpc';
|
||||
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
||||
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
|
||||
import { IProductService } from 'vs/platform/product/common/product';
|
||||
import Severity from 'vs/base/common/severity';
|
||||
import { localize } from 'vs/nls';
|
||||
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
|
||||
|
||||
//#region Extension Tips
|
||||
|
||||
@@ -174,63 +176,6 @@ export class SimpleLogService extends ConsoleLogService { }
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region Multi Extension Management
|
||||
|
||||
export class SimpleMultiExtensionsManagementService implements IExtensionManagementService {
|
||||
|
||||
_serviceBrand: any;
|
||||
|
||||
onInstallExtension = Event.None;
|
||||
onDidInstallExtension = Event.None;
|
||||
onUninstallExtension = Event.None;
|
||||
onDidUninstallExtension = Event.None;
|
||||
|
||||
zip(extension: ILocalExtension): Promise<URI> {
|
||||
// @ts-ignore
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
unzip(zipLocation: URI, type: ExtensionType): Promise<IExtensionIdentifier> {
|
||||
// @ts-ignore
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
install(vsix: URI): Promise<ILocalExtension> {
|
||||
// @ts-ignore
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
installFromGallery(extension: IGalleryExtension): Promise<ILocalExtension> {
|
||||
// @ts-ignore
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
uninstall(extension: ILocalExtension, force?: boolean): Promise<void> {
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
reinstallFromGallery(extension: ILocalExtension): Promise<void> {
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
getInstalled(type?: ExtensionType): Promise<ILocalExtension[]> {
|
||||
// @ts-ignore
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
getExtensionsReport(): Promise<IReportedExtension[]> {
|
||||
// @ts-ignore
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
updateMetadata(local: ILocalExtension, metadata: IGalleryMetadata): Promise<ILocalExtension> {
|
||||
// @ts-ignore
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region Update
|
||||
|
||||
export class SimpleUpdateService implements IUpdateService {
|
||||
@@ -571,41 +516,6 @@ registerSingleton(IWindowService, SimpleWindowService);
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region ExtensionHostDebugService
|
||||
|
||||
export class SimpleExtensionHostDebugService extends ExtensionHostDebugChannelClient {
|
||||
|
||||
constructor(
|
||||
@IRemoteAgentService remoteAgentService: IRemoteAgentService,
|
||||
//@IWindowService windowService: IWindowService,
|
||||
@IEnvironmentService environmentService: IEnvironmentService
|
||||
) {
|
||||
const connection = remoteAgentService.getConnection();
|
||||
|
||||
if (!connection) {
|
||||
throw new Error('Missing agent connection');
|
||||
}
|
||||
|
||||
super(connection.getChannel(ExtensionHostDebugBroadcastChannel.ChannelName));
|
||||
|
||||
this._register(this.onReload(event => {
|
||||
if (environmentService.isExtensionDevelopment && environmentService.debugExtensionHost.debugId === event.sessionId) {
|
||||
//windowService.reloadWindow();
|
||||
window.location.reload();
|
||||
}
|
||||
}));
|
||||
this._register(this.onClose(event => {
|
||||
if (environmentService.isExtensionDevelopment && environmentService.debugExtensionHost.debugId === event.sessionId) {
|
||||
//this._windowService.closeWindow();
|
||||
window.close();
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
registerSingleton(IExtensionHostDebugService, SimpleExtensionHostDebugService);
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region Window
|
||||
|
||||
export class SimpleWindowsService implements IWindowsService {
|
||||
@@ -621,7 +531,10 @@ export class SimpleWindowsService implements IWindowsService {
|
||||
readonly onRecentlyOpenedChange: Event<void> = Event.None;
|
||||
|
||||
constructor(
|
||||
@IWorkbenchEnvironmentService private readonly workbenchEnvironmentService: IWorkbenchEnvironmentService
|
||||
@IWorkbenchEnvironmentService private readonly workbenchEnvironmentService: IWorkbenchEnvironmentService,
|
||||
@IDialogService private readonly dialogService: IDialogService,
|
||||
@IProductService private readonly productService: IProductService,
|
||||
@IClipboardService private readonly clipboardService: IClipboardService
|
||||
) {
|
||||
}
|
||||
isFocused(_windowId: number): Promise<boolean> {
|
||||
@@ -728,6 +641,8 @@ export class SimpleWindowsService implements IWindowsService {
|
||||
}
|
||||
|
||||
relaunch(_options: { addArgs?: string[], removeArgs?: string[] }): Promise<void> {
|
||||
window.location.reload();
|
||||
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
@@ -753,6 +668,15 @@ export class SimpleWindowsService implements IWindowsService {
|
||||
// we pass the "ParsedArgs" as query parameters of the URL
|
||||
|
||||
let newAddress = `${document.location.origin}/?`;
|
||||
let gotFolder = false;
|
||||
|
||||
const addQueryParameter = (key: string, value: string) => {
|
||||
const lastChar = newAddress.charAt(newAddress.length - 1);
|
||||
if (lastChar !== '?' && lastChar !== '&') {
|
||||
newAddress += '&';
|
||||
}
|
||||
newAddress += `${key}=${encodeURIComponent(value)}`;
|
||||
};
|
||||
|
||||
const f = args['folder-uri'];
|
||||
if (f) {
|
||||
@@ -765,9 +689,14 @@ export class SimpleWindowsService implements IWindowsService {
|
||||
u = URI.parse(f);
|
||||
}
|
||||
if (u) {
|
||||
newAddress += `folder=${encodeURIComponent(u.path)}`;
|
||||
gotFolder = true;
|
||||
addQueryParameter('folder', u.path);
|
||||
}
|
||||
}
|
||||
if (!gotFolder) {
|
||||
// request empty window
|
||||
addQueryParameter('ew', 'true');
|
||||
}
|
||||
|
||||
const ep = args['extensionDevelopmentPath'];
|
||||
if (ep) {
|
||||
@@ -780,22 +709,24 @@ export class SimpleWindowsService implements IWindowsService {
|
||||
u = ep;
|
||||
}
|
||||
if (u) {
|
||||
newAddress += `&edp=${encodeURIComponent(u)}`;
|
||||
addQueryParameter('edp', u);
|
||||
}
|
||||
}
|
||||
|
||||
const di = args['debugId'];
|
||||
if (di) {
|
||||
newAddress += `&di=${encodeURIComponent(di)}`;
|
||||
addQueryParameter('di', di);
|
||||
}
|
||||
|
||||
const ibe = args['inspect-brk-extensions'];
|
||||
if (ibe) {
|
||||
newAddress += `&ibe=${encodeURIComponent(ibe)}`;
|
||||
addQueryParameter('ibe', ibe);
|
||||
}
|
||||
|
||||
// add connection token
|
||||
newAddress += `${this.workbenchEnvironmentService.configuration.connectionToken ? `tkn=${this.workbenchEnvironmentService.configuration.connectionToken}` : ''}`;
|
||||
if (this.workbenchEnvironmentService.configuration.connectionToken) {
|
||||
addQueryParameter('tkn', this.workbenchEnvironmentService.configuration.connectionToken);
|
||||
}
|
||||
|
||||
window.open(newAddress);
|
||||
|
||||
@@ -873,8 +804,20 @@ export class SimpleWindowsService implements IWindowsService {
|
||||
throw new Error('not implemented');
|
||||
}
|
||||
|
||||
openAboutDialog(): Promise<void> {
|
||||
return Promise.resolve();
|
||||
async openAboutDialog(): Promise<void> {
|
||||
const detail = localize('aboutDetail',
|
||||
"Version: {0}\nCommit: {1}\nDate: {2}\nBrowser: {3}",
|
||||
this.productService.version || 'Unknown',
|
||||
this.productService.commit || 'Unknown',
|
||||
this.productService.date || 'Unknown',
|
||||
navigator.userAgent
|
||||
);
|
||||
|
||||
const result = await this.dialogService.show(Severity.Info, this.productService.nameLong, [localize('copy', "Copy"), localize('ok', "OK")], { detail });
|
||||
|
||||
if (result === 0) {
|
||||
this.clipboardService.writeText(detail);
|
||||
}
|
||||
}
|
||||
|
||||
resolveProxy(windowId: number, url: string): Promise<string | undefined> {
|
||||
|
||||
@@ -237,7 +237,7 @@ import { isMacintosh, isWindows, isLinux, isWeb } from 'vs/base/common/platform'
|
||||
'workbench.useExperimentalGridLayout': {
|
||||
'type': 'boolean',
|
||||
'description': nls.localize('workbench.useExperimentalGridLayout', "Enables the grid layout for the workbench. This setting may enable additional layout options for workbench components."),
|
||||
'default': false,
|
||||
'default': true,
|
||||
'scope': ConfigurationScope.APPLICATION
|
||||
}
|
||||
}
|
||||
@@ -246,7 +246,7 @@ import { isMacintosh, isWindows, isLinux, isWeb } from 'vs/base/common/platform'
|
||||
// Window
|
||||
|
||||
let windowTitleDescription = nls.localize('windowTitle', "Controls the window title based on the active editor. Variables are substituted based on the context:");
|
||||
windowTitleDescription += [
|
||||
windowTitleDescription += '\n- ' + [
|
||||
nls.localize('activeEditorShort', "`\${activeEditorShort}`: the file name (e.g. myFile.txt)."),
|
||||
nls.localize('activeEditorMedium', "`\${activeEditorMedium}`: the path of the file relative to the workspace folder (e.g. myFolder/myFileFolder/myFile.txt)."),
|
||||
nls.localize('activeEditorLong', "`\${activeEditorLong}`: the full path of the file (e.g. /Users/Development/myFolder/myFileFolder/myFile.txt)."),
|
||||
|
||||
@@ -25,7 +25,7 @@ import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
|
||||
import { IPanelService } from 'vs/workbench/services/panel/common/panelService';
|
||||
import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
|
||||
import { LifecyclePhase, ILifecycleService, WillShutdownEvent } from 'vs/platform/lifecycle/common/lifecycle';
|
||||
import { LifecyclePhase, ILifecycleService, WillShutdownEvent, BeforeShutdownEvent } from 'vs/platform/lifecycle/common/lifecycle';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { NotificationService } from 'vs/workbench/services/notification/common/notificationService';
|
||||
import { NotificationsCenter } from 'vs/workbench/browser/parts/notifications/notificationsCenter';
|
||||
@@ -47,6 +47,9 @@ import { Layout } from 'vs/workbench/browser/layout';
|
||||
|
||||
export class Workbench extends Layout {
|
||||
|
||||
private readonly _onBeforeShutdown = this._register(new Emitter<BeforeShutdownEvent>());
|
||||
readonly onBeforeShutdown: Event<BeforeShutdownEvent> = this._onBeforeShutdown.event;
|
||||
|
||||
private readonly _onShutdown = this._register(new Emitter<void>());
|
||||
readonly onShutdown: Event<void> = this._onShutdown.event;
|
||||
|
||||
@@ -182,7 +185,7 @@ export class Workbench extends Layout {
|
||||
|
||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
// NOTE: DO NOT ADD ANY OTHER SERVICE INTO THE COLLECTION HERE.
|
||||
// CONTRIBUTE IT VIA WORKBENCH.MAIN.TS AND registerSingleton().
|
||||
// CONTRIBUTE IT VIA WORKBENCH.DESKTOP.MAIN.TS AND registerSingleton().
|
||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
// All Contributed Services
|
||||
@@ -225,6 +228,7 @@ export class Workbench extends Layout {
|
||||
): void {
|
||||
|
||||
// Lifecycle
|
||||
this._register(lifecycleService.onBeforeShutdown(event => this._onBeforeShutdown.fire(event)));
|
||||
this._register(lifecycleService.onWillShutdown(event => this._onWillShutdown.fire(event)));
|
||||
this._register(lifecycleService.onShutdown(() => {
|
||||
this._onShutdown.fire();
|
||||
@@ -238,7 +242,7 @@ export class Workbench extends Layout {
|
||||
this._register(storageService.onWillSaveState(e => this.storeFontInfo(e, storageService)));
|
||||
}
|
||||
|
||||
private fontAliasing: 'default' | 'antialiased' | 'none' | 'auto';
|
||||
private fontAliasing: 'default' | 'antialiased' | 'none' | 'auto' | undefined;
|
||||
private setFontAliasing(configurationService: IConfigurationService) {
|
||||
const aliasing = configurationService.getValue<'default' | 'antialiased' | 'none' | 'auto'>('workbench.fontAliasing');
|
||||
if (this.fontAliasing === aliasing) {
|
||||
@@ -294,10 +298,7 @@ export class Workbench extends Layout {
|
||||
'monaco-workbench',
|
||||
platformClass,
|
||||
isWeb ? 'web' : undefined,
|
||||
this.state.sideBar.hidden ? 'nosidebar' : undefined,
|
||||
this.state.panel.hidden ? 'nopanel' : undefined,
|
||||
this.state.statusBar.hidden ? 'nostatusbar' : undefined,
|
||||
this.state.fullscreen ? 'fullscreen' : undefined
|
||||
...this.getLayoutClasses()
|
||||
]);
|
||||
|
||||
addClasses(this.container, ...workbenchClasses);
|
||||
|
||||
Reference in New Issue
Block a user