/********************************************************************************
 * Copyright (C) 2018 TypeFox and others.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the Eclipse
 * Public License v. 2.0 are satisfied: GNU General Public License, version 2
 * with the GNU Classpath Exception which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 ********************************************************************************/ import { injectable , inject , interfaces , optional } from 'inversify' ; import { Widget } from '@phosphor/widgets' ; import { MenuModelRegistry , Command , CommandContribution , MenuContribution , CommandRegistry } from '../../common' ; import { KeybindingContribution , KeybindingRegistry } from '../keybinding' ; import { WidgetManager } from '../widget-manager' ; import { CommonMenus } from '../common-frontend-contribution' ; import { ApplicationShell } from './application-shell' ; import { QuickViewService } from '../quick-input' ; export interface OpenViewArguments extends ApplicationShell . WidgetOptions { toggle ? : boolean ; activate ? : boolean ; reveal ? : boolean ; } export interface ViewContributionOptions { widgetId : string ; viewContainerId ? : string ; widgetName : string ; defaultWidgetOptions : ApplicationShell . WidgetOptions ; toggleCommandId ? : string ; toggleKeybinding ? : string ; } export function bindViewContribution < T extends AbstractViewContribution < any > > ( bind , identifier ) { const syntax = bind < T > ( identifier ) . toSelf ( ) . inSingletonScope ( ) ; bind ( CommandContribution ) . toService ( identifier ) ; bind ( KeybindingContribution ) . toService ( identifier ) ; bind ( MenuContribution ) . toService ( identifier ) ; return syntax ; } /**
 * An abstract superclass for frontend contributions that add a view to the application shell.
 */ @ injectable ( ) export abstract class AbstractViewContribution < T extends Widget > implements CommandContribution , MenuContribution , KeybindingContribution { @ inject ( WidgetManager ) protected readonly widgetManager : WidgetManager ; @ inject ( ApplicationShell ) protected readonly shell : ApplicationShell ; @ inject ( QuickViewService ) @ optional ( ) protected readonly quickView : QuickViewService ; readonly toggleCommand ? : Command ; constructor ( protected readonly options ) { if ( options . toggleCommandId ) { this . toggleCommand = { id : options . toggleCommandId , label : 'Toggle ' + this . viewLabel + ' View' } ; } } get viewId ( ) : string { return this . options . widgetId ; } get viewLabel ( ) : string { return this . options . widgetName ; } get defaultViewOptions ( ) : ApplicationShell . WidgetOptions { return this . options . defaultWidgetOptions ; } get widget ( ) : Promise < T > { return this . widgetManager . getOrCreateWidget ( this . viewId ) ; } tryGetWidget ( ) { return this . widgetManager . tryGetWidget ( this . viewId ) ; } async openView ( args = { } ) { const shell = this . shell ; const widget = await this . widgetManager . getOrCreateWidget ( this . options . viewContainerId || this . viewId ) ; const tabBar = shell . getTabBarFor ( widget ) ; const area = shell . getAreaFor ( widget ) ; if ( ! tabBar ) { const widgetArgs = { ... this . defaultViewOptions , ... args } ; await shell . addWidget ( widget , widgetArgs ) ; } else if ( args . toggle && area && shell . isExpanded ( area ) && tabBar . currentTitle === widget . title ) { switch ( area ) { case 'left' : case 'right' : await shell . collapsePanel ( area ) ; break ; case 'bottom' : if ( shell . bottomAreaTabBars . length === 1 ) { await shell . collapsePanel ( 'bottom' ) ; } break ; default : await this . closeView ( ) ; } return this . widget ; } if ( widget . isAttached && args . activate ) { await shell . activateWidget ( this . viewId ) ; } else if ( widget . isAttached && args . reveal ) { await shell . revealWidget ( this . viewId ) ; } return this . widget ; } registerCommands ( commands ) { if ( this . toggleCommand ) { commands . registerCommand ( this . toggleCommand , { execute : ( ) => this . toggleView ( ) } ) ; } this . quickView ?. registerItem ( { label : this . viewLabel , open : ( ) => this . openView ( { activate : true } ) } ) ; } async closeView ( ) { const widget = await this . shell . closeWidget ( this . viewId ) ; return widget as T | undefined ; } toggleView ( ) { return this . openView ( { toggle : true , activate : true } ) ; } registerMenus ( menus ) { if ( this . toggleCommand ) { menus . registerMenuAction ( CommonMenus . VIEW_VIEWS , { commandId : this . toggleCommand . id , label : this . viewLabel } ) ; } } registerKeybindings ( keybindings ) { if ( this . toggleCommand && this . options . toggleKeybinding ) { keybindings . registerKeybinding ( { command : this . toggleCommand . id , keybinding : this . options . toggleKeybinding } ) ; } } }