diff --git a/src/vs/workbench/contrib/debug/browser/media/debugViewlet.css b/src/vs/workbench/contrib/debug/browser/media/debugViewlet.css index 2408b52df0264fb99f911ea1a0e815fbda4625fd..8a1dd5969f9ba552d12802124acd6e6b79cc5563 100644 --- a/src/vs/workbench/contrib/debug/browser/media/debugViewlet.css +++ b/src/vs/workbench/contrib/debug/browser/media/debugViewlet.css @@ -13,31 +13,6 @@ height: 100%; } -.debug-pane .debug-start-view { - padding: 0 20px 0 20px; -} - -.debug-pane .debug-start-view .monaco-button, -.debug-pane .debug-start-view .section { - margin-top: 20px; -} - -.debug-pane .debug-start-view .top-section { - margin-top: 10px; -} - -.debug-pane .debug-start-view .monaco-button { - max-width: 260px; - margin-left: auto; - margin-right: auto; - display: block; -} - -.debug-pane .debug-start-view .click { - cursor: pointer; - color: #007ACC; -} - .monaco-workbench .debug-action.notification:after { content: ''; width: 6px; diff --git a/src/vs/workbench/contrib/debug/browser/startView.ts b/src/vs/workbench/contrib/debug/browser/startView.ts index f561b8cc42b112f5f79e884274e1bfe0c3f365ed..89a25705c9483235ade182bd7a4030f4e80792af 100644 --- a/src/vs/workbench/contrib/debug/browser/startView.ts +++ b/src/vs/workbench/contrib/debug/browser/startView.ts @@ -3,64 +3,33 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as dom from 'vs/base/browser/dom'; -import { Button } from 'vs/base/browser/ui/button/button'; import { IViewletViewOptions } from 'vs/workbench/browser/parts/views/viewsViewlet'; -import { attachButtonStyler } from 'vs/platform/theme/common/styler'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { IContextKeyService, RawContextKey, IContextKey } from 'vs/platform/contextkey/common/contextkey'; import { localize } from 'vs/nls'; -import { ICommandService } from 'vs/platform/commands/common/commands'; import { StartAction, ConfigureAction } from 'vs/workbench/contrib/debug/browser/debugActions'; import { IDebugService } from 'vs/workbench/contrib/debug/common/debug'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; -import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; -import { IFileDialogService } from 'vs/platform/dialogs/common/dialogs'; -import { equals } from 'vs/base/common/arrays'; import { IViewPaneOptions, ViewPane } from 'vs/workbench/browser/parts/views/viewPaneContainer'; -import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; -import { KeyCode } from 'vs/base/common/keyCodes'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import { IViewDescriptorService } from 'vs/workbench/common/views'; +import { IViewDescriptorService, IViewsRegistry, Extensions } from 'vs/workbench/common/views'; +import { Registry } from 'vs/platform/registry/common/platform'; import { IOpenerService } from 'vs/platform/opener/common/opener'; -const $ = dom.$; +import { WorkbenchStateContext } from 'vs/workbench/browser/contextkeys'; +import { OpenFolderAction, OpenFileAction, OpenFileFolderAction } from 'vs/workbench/browser/actions/workspaceActions'; +import { isMacintosh } from 'vs/base/common/platform'; -interface DebugStartMetrics { - debuggers?: string[]; -} -type DebugStartMetricsClassification = { - debuggers?: { classification: 'SystemMetaData', purpose: 'FeatureInsight' }; -}; - -function createClickElement(textContent: string, action: () => any): HTMLSpanElement { - const clickElement = $('span.click'); - clickElement.textContent = textContent; - clickElement.onclick = action; - clickElement.tabIndex = 0; - clickElement.onkeyup = (e) => { - const keyboardEvent = new StandardKeyboardEvent(e); - if (keyboardEvent.keyCode === KeyCode.Enter || (keyboardEvent.keyCode === KeyCode.Space)) { - action(); - } - }; - - return clickElement; -} +const CONTEXT_DEBUGGER_INTERESTED = new RawContextKey('debuggerInterested', false); export class StartView extends ViewPane { static ID = 'workbench.debug.startView'; static LABEL = localize('start', "Start"); - private debugButton!: Button; - private firstMessageContainer!: HTMLElement; - private secondMessageContainer!: HTMLElement; - private clickElement: HTMLElement | undefined; - private debuggerLabels: string[] | undefined = undefined; + private debuggerInterestedContext: IContextKey; constructor( options: IViewletViewOptions, @@ -69,125 +38,45 @@ export class StartView extends ViewPane { @IContextMenuService contextMenuService: IContextMenuService, @IConfigurationService configurationService: IConfigurationService, @IContextKeyService contextKeyService: IContextKeyService, - @ICommandService private readonly commandService: ICommandService, @IDebugService private readonly debugService: IDebugService, @IEditorService private readonly editorService: IEditorService, - @IWorkspaceContextService private readonly workspaceContextService: IWorkspaceContextService, - @IFileDialogService private readonly dialogService: IFileDialogService, @IInstantiationService instantiationService: IInstantiationService, @IViewDescriptorService viewDescriptorService: IViewDescriptorService, - @ITelemetryService private readonly telemetryService: ITelemetryService, @IOpenerService openerService: IOpenerService, ) { super({ ...(options as IViewPaneOptions), ariaHeaderLabel: localize('debugStart', "Debug Start Section") }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService); - this._register(editorService.onDidActiveEditorChange(() => this.updateView())); - this._register(this.debugService.getConfigurationManager().onDidRegisterDebugger(() => this.updateView())); - } - - private updateView(): void { - const activeEditor = this.editorService.activeTextEditorWidget; - const debuggerLabels = this.debugService.getConfigurationManager().getDebuggerLabelsForEditor(activeEditor); - if (!equals(this.debuggerLabels, debuggerLabels)) { - this.debuggerLabels = debuggerLabels; - const enabled = this.debuggerLabels.length > 0; - - this.debugButton.enabled = enabled; - const debugKeybinding = this.keybindingService.lookupKeybinding(StartAction.ID); - let debugLabel = this.debuggerLabels.length !== 1 ? localize('debug', "Run and Debug") : localize('debugWith', "Run and Debug {0}", this.debuggerLabels[0]); - if (debugKeybinding) { - debugLabel += ` (${debugKeybinding.getLabel()})`; - } - this.debugButton.label = debugLabel; - - const emptyWorkbench = this.workspaceContextService.getWorkbenchState() === WorkbenchState.EMPTY; - this.firstMessageContainer.innerHTML = ''; - this.secondMessageContainer.innerHTML = ''; - const secondMessageElement = $('span'); - this.secondMessageContainer.appendChild(secondMessageElement); - - const setSecondMessage = () => { - secondMessageElement.textContent = localize('specifyHowToRun', "To customize Run and Debug"); - this.clickElement = createClickElement(localize('configure', " create a launch.json file."), () => { - this.telemetryService.publicLog2('debugStart.configure', { debuggers: this.debuggerLabels }); - this.commandService.executeCommand(ConfigureAction.ID); - }); - this.secondMessageContainer.appendChild(this.clickElement); - }; - const setSecondMessageWithFolder = () => { - secondMessageElement.textContent = localize('noLaunchConfiguration', "To customize Run and Debug, "); - this.clickElement = createClickElement(localize('openFolder', " open a folder"), () => { - this.telemetryService.publicLog2('debugStart.openFolder', { debuggers: this.debuggerLabels }); - this.dialogService.pickFolderAndOpen({ forceNewWindow: false }); - }); - this.secondMessageContainer.appendChild(this.clickElement); - - const moreText = $('span.moreText'); - moreText.textContent = localize('andconfigure', " and create a launch.json file."); - this.secondMessageContainer.appendChild(moreText); - }; - - if (enabled && !emptyWorkbench) { - setSecondMessage(); - } - - if (enabled && emptyWorkbench) { - setSecondMessageWithFolder(); - } - - if (!enabled && !emptyWorkbench) { - const firstMessageElement = $('span'); - this.firstMessageContainer.appendChild(firstMessageElement); - firstMessageElement.textContent = localize('simplyDebugAndRun', "Open a file which can be debugged or run."); - setSecondMessage(); - } - - if (!enabled && emptyWorkbench) { - this.clickElement = createClickElement(localize('openFile', "Open a file"), () => { - this.telemetryService.publicLog2('debugStart.openFile'); - this.dialogService.pickFileAndOpen({ forceNewWindow: false }); - }); - this.firstMessageContainer.appendChild(this.clickElement); - const firstMessageElement = $('span'); - this.firstMessageContainer.appendChild(firstMessageElement); - firstMessageElement.textContent = localize('canBeDebuggedOrRun', " which can be debugged or run."); - - setSecondMessageWithFolder(); - } - } - } - - protected renderBody(container: HTMLElement): void { - super.renderBody(container); - - this.firstMessageContainer = $('.top-section'); - container.appendChild(this.firstMessageContainer); - - this.debugButton = new Button(container); - this._register(this.debugButton.onDidClick(() => { - this.commandService.executeCommand(StartAction.ID); - this.telemetryService.publicLog2('debugStart.runAndDebug', { debuggers: this.debuggerLabels }); - })); - attachButtonStyler(this.debugButton, this.themeService); - - dom.addClass(this.element, 'debug-pane'); - dom.addClass(container, 'debug-start-view'); - - this.secondMessageContainer = $('.section'); - container.appendChild(this.secondMessageContainer); - - this.updateView(); + this.debuggerInterestedContext = CONTEXT_DEBUGGER_INTERESTED.bindTo(contextKeyService); + const setContextKey = () => { + const activeEditor = this.editorService.activeTextEditorWidget; + const debuggerLabels = this.debugService.getConfigurationManager().getDebuggerLabelsForEditor(activeEditor); + this.debuggerInterestedContext.set(debuggerLabels.length > 0); + }; + this._register(editorService.onDidActiveEditorChange(setContextKey)); + this._register(this.debugService.getConfigurationManager().onDidRegisterDebugger(setContextKey)); } - protected layoutBody(_: number, __: number): void { - // no-op - } - - focus(): void { - if (this.debugButton.enabled) { - this.debugButton.focus(); - } else if (this.clickElement) { - this.clickElement.focus(); - } + shouldShowWelcome(): boolean { + return true; } } + +const viewsRegistry = Registry.as(Extensions.ViewsRegistry); +viewsRegistry.registerViewWelcomeContent(StartView.ID, { + content: localize('openAFileWhichCanBeDebugged', "[Open a file](command:{0}) which can be debugged or run.", isMacintosh ? OpenFileFolderAction.ID : OpenFileAction.ID), + when: CONTEXT_DEBUGGER_INTERESTED.toNegated() +}); + +viewsRegistry.registerViewWelcomeContent(StartView.ID, { + content: localize('runAndDebugAction', "[Run and Debug](command:{0})", StartAction.ID) +}); + +viewsRegistry.registerViewWelcomeContent(StartView.ID, { + content: localize('customizeRunAndDebug', "To customize Run and Debug [create a launch.json file](command:{0}).", ConfigureAction.ID), + when: WorkbenchStateContext.notEqualsTo('empty') +}); + +viewsRegistry.registerViewWelcomeContent(StartView.ID, { + content: localize('customizeRunAndDebugOpenFolder', "To customize Run and Debug, [open a folder](command:{0}) and create a launch.json file.", isMacintosh ? OpenFileFolderAction.ID : OpenFolderAction.ID), + when: WorkbenchStateContext.isEqualTo('empty') +});