mirror of
https://github.com/microsoft/vscode.git
synced 2026-09-06 14:34:17 +01:00
Merge pull request #59270 from Microsoft/octref/44625
Prev/Next Panel/Sidebar view. Part of #44625
This commit is contained in:
@@ -4,24 +4,30 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import 'vs/css!./media/activityaction';
|
||||
import * as nls from 'vs/nls';
|
||||
import * as DOM from 'vs/base/browser/dom';
|
||||
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
|
||||
import { EventType as TouchEventType, GestureEvent } from 'vs/base/browser/touch';
|
||||
import { Action } from 'vs/base/common/actions';
|
||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { ViewletDescriptor } from 'vs/workbench/browser/viewlet';
|
||||
import { IActivity, IGlobalActivity } from 'vs/workbench/common/activity';
|
||||
import { dispose } from 'vs/base/common/lifecycle';
|
||||
import { IViewletService, } from 'vs/workbench/services/viewlet/browser/viewlet';
|
||||
import { IPartService, Parts } from 'vs/workbench/services/part/common/partService';
|
||||
import { IThemeService, ITheme, registerThemingParticipant, ICssStyleCollector } from 'vs/platform/theme/common/themeService';
|
||||
import { activeContrastBorder, focusBorder } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
|
||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { ActivityAction, ActivityActionItem, ICompositeBarColors, ToggleCompositePinnedAction, ICompositeBar } from 'vs/workbench/browser/parts/compositeBarActions';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { dispose } from 'vs/base/common/lifecycle';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { SyncActionDescriptor } from 'vs/platform/actions/common/actions';
|
||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { activeContrastBorder, focusBorder } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { ICssStyleCollector, ITheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
|
||||
import { ActivityAction, ActivityActionItem, ICompositeBar, ICompositeBarColors, ToggleCompositePinnedAction } from 'vs/workbench/browser/parts/compositeBarActions';
|
||||
import { ViewletDescriptor } from 'vs/workbench/browser/viewlet';
|
||||
import { Extensions as ActionExtensions, IWorkbenchActionRegistry } from 'vs/workbench/common/actions';
|
||||
import { IActivity, IGlobalActivity } from 'vs/workbench/common/activity';
|
||||
import { ACTIVITY_BAR_FOREGROUND } from 'vs/workbench/common/theme';
|
||||
import { IActivityService } from 'vs/workbench/services/activity/common/activity';
|
||||
import { IPartService, Parts } from 'vs/workbench/services/part/common/partService';
|
||||
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
|
||||
|
||||
export class ViewletActivityAction extends ActivityAction {
|
||||
|
||||
@@ -188,6 +194,77 @@ export class PlaceHolderToggleCompositePinnedAction extends ToggleCompositePinne
|
||||
}
|
||||
}
|
||||
|
||||
class SwitchSidebarViewAction extends Action {
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
name: string,
|
||||
@IViewletService private viewletService: IViewletService,
|
||||
@IActivityService private activityService: IActivityService
|
||||
) {
|
||||
super(id, name);
|
||||
}
|
||||
|
||||
run(offset: number): TPromise<any> {
|
||||
const pinnedViewletIds = this.activityService.getPinnedViewletIds();
|
||||
|
||||
const activeViewlet = this.viewletService.getActiveViewlet();
|
||||
if (!activeViewlet) {
|
||||
return TPromise.as(null);
|
||||
}
|
||||
let targetViewletId: string;
|
||||
for (let i = 0; i < pinnedViewletIds.length; i++) {
|
||||
if (pinnedViewletIds[i] === activeViewlet.getId()) {
|
||||
targetViewletId = pinnedViewletIds[(i + pinnedViewletIds.length + offset) % pinnedViewletIds.length];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return this.viewletService.openViewlet(targetViewletId, true);
|
||||
}
|
||||
}
|
||||
|
||||
export class PreviousSidebarViewAction extends SwitchSidebarViewAction {
|
||||
|
||||
static readonly ID = 'workbench.action.previousSidebarView';
|
||||
static LABEL = nls.localize('previousSidebarView', 'Previous Sidebar View');
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
name: string,
|
||||
@IViewletService viewletService: IViewletService,
|
||||
@IActivityService activityService: IActivityService
|
||||
) {
|
||||
super(id, name, viewletService, activityService);
|
||||
}
|
||||
|
||||
run(): TPromise<any> {
|
||||
return super.run(-1);
|
||||
}
|
||||
}
|
||||
|
||||
export class NextSidebarViewAction extends SwitchSidebarViewAction {
|
||||
|
||||
static readonly ID = 'workbench.action.nextSidebarView';
|
||||
static LABEL = nls.localize('nextSidebarView', 'Next Sidebar View');
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
name: string,
|
||||
@IViewletService viewletService: IViewletService,
|
||||
@IActivityService activityService: IActivityService
|
||||
) {
|
||||
super(id, name, viewletService, activityService);
|
||||
}
|
||||
|
||||
run(): TPromise<any> {
|
||||
return super.run(1);
|
||||
}
|
||||
}
|
||||
|
||||
const registry = Registry.as<IWorkbenchActionRegistry>(ActionExtensions.WorkbenchActions);
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(PreviousSidebarViewAction, PreviousSidebarViewAction.ID, PreviousSidebarViewAction.LABEL), 'View: Open Previous Sidebar View', nls.localize('view', "View"));
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(NextSidebarViewAction, NextSidebarViewAction.ID, NextSidebarViewAction.LABEL), 'View: Open Next Sidebar View', nls.localize('view', "View"));
|
||||
|
||||
registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => {
|
||||
|
||||
const activeForegroundColor = theme.getColor(ACTIVITY_BAR_FOREGROUND);
|
||||
|
||||
@@ -304,8 +304,12 @@ export class ActivitybarPart extends Part {
|
||||
}
|
||||
}
|
||||
|
||||
getPinned(): string[] {
|
||||
return this.viewletService.getViewlets().map(v => v.id).filter(id => this.compositeBar.isPinned(id));
|
||||
getPinnedViewletIds(): string[] {
|
||||
const pinnedCompositeIds = this.compositeBar.getPinnedComposites().map(v => v.id);
|
||||
return this.viewletService.getViewlets()
|
||||
.filter(v => this.compositeBar.isPinned(v.id))
|
||||
.sort((v1, v2) => pinnedCompositeIds.indexOf(v1.id) - pinnedCompositeIds.indexOf(v2.id))
|
||||
.map(v => v.id);
|
||||
}
|
||||
|
||||
layout(dimension: Dimension): Dimension[] {
|
||||
|
||||
@@ -70,6 +70,10 @@ export class CompositeBar extends Widget implements ICompositeBar {
|
||||
return this.model.items;
|
||||
}
|
||||
|
||||
getPinnedComposites(): ICompositeBarItem[] {
|
||||
return this.model.pinnedItems;
|
||||
}
|
||||
|
||||
create(parent: HTMLElement): HTMLElement {
|
||||
const actionBarDiv = parent.appendChild($('.composite-bar'));
|
||||
this.compositeSwitcherBar = this._register(new ActionBar(actionBarDiv, {
|
||||
@@ -458,6 +462,10 @@ class CompositeBarModel {
|
||||
return this.items.filter(item => item.visible);
|
||||
}
|
||||
|
||||
get pinnedItems(): ICompositeBarItem[] {
|
||||
return this.items.filter(item => item.visible && item.pinned);
|
||||
}
|
||||
|
||||
private createCompositeBarItem(id: string, name: string, order: number, pinned: boolean, visible: boolean): ICompositeBarItem {
|
||||
const options = this.options;
|
||||
return {
|
||||
|
||||
@@ -179,6 +179,69 @@ export class PanelActivityAction extends ActivityAction {
|
||||
}
|
||||
}
|
||||
|
||||
export class SwitchPanelViewAction extends Action {
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
name: string,
|
||||
@IPanelService private panelService: IPanelService
|
||||
) {
|
||||
super(id, name);
|
||||
}
|
||||
|
||||
run(offset: number): TPromise<any> {
|
||||
const pinnedPanels = this.panelService.getPinnedPanels();
|
||||
const activePanel = this.panelService.getActivePanel();
|
||||
if (!activePanel) {
|
||||
return TPromise.as(null);
|
||||
}
|
||||
let targetPanelId: string;
|
||||
for (let i = 0; i < pinnedPanels.length; i++) {
|
||||
if (pinnedPanels[i].id === activePanel.getId()) {
|
||||
targetPanelId = pinnedPanels[(i + pinnedPanels.length + offset) % pinnedPanels.length].id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return this.panelService.openPanel(targetPanelId, true);
|
||||
}
|
||||
}
|
||||
|
||||
export class PreviousPanelViewAction extends SwitchPanelViewAction {
|
||||
|
||||
static readonly ID = 'workbench.action.previousPanelView';
|
||||
static LABEL = nls.localize('previousPanelView', 'Previous Panel View');
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
name: string,
|
||||
@IPanelService panelService: IPanelService
|
||||
) {
|
||||
super(id, name, panelService);
|
||||
}
|
||||
|
||||
run(): TPromise<any> {
|
||||
return super.run(-1);
|
||||
}
|
||||
}
|
||||
|
||||
export class NextPanelViewAction extends SwitchPanelViewAction {
|
||||
|
||||
static readonly ID = 'workbench.action.nextPanelView';
|
||||
static LABEL = nls.localize('nextPanelView', 'Next Panel View');
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
name: string,
|
||||
@IPanelService panelService: IPanelService
|
||||
) {
|
||||
super(id, name, panelService);
|
||||
}
|
||||
|
||||
public run(): TPromise<any> {
|
||||
return super.run(1);
|
||||
}
|
||||
}
|
||||
|
||||
const actionRegistry = Registry.as<IWorkbenchActionRegistry>(WorkbenchExtensions.WorkbenchActions);
|
||||
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(TogglePanelAction, TogglePanelAction.ID, TogglePanelAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.KEY_J }), 'View: Toggle Panel', nls.localize('view', "View"));
|
||||
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(FocusPanelAction, FocusPanelAction.ID, FocusPanelAction.LABEL), 'View: Focus into Panel', nls.localize('view', "View"));
|
||||
@@ -186,6 +249,8 @@ actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ToggleMaximizedP
|
||||
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ClosePanelAction, ClosePanelAction.ID, ClosePanelAction.LABEL), 'View: Close Panel', nls.localize('view', "View"));
|
||||
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(TogglePanelPositionAction, TogglePanelPositionAction.ID, TogglePanelPositionAction.LABEL), 'View: Toggle Panel Position', nls.localize('view', "View"));
|
||||
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ToggleMaximizedPanelAction, ToggleMaximizedPanelAction.ID, undefined), 'View: Toggle Panel Position', nls.localize('view', "View"));
|
||||
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(PreviousPanelViewAction, PreviousPanelViewAction.ID, PreviousPanelViewAction.LABEL), 'View: Open Previous Panel View', nls.localize('view', "View"));
|
||||
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(NextPanelViewAction, NextPanelViewAction.ID, NextPanelViewAction.LABEL), 'View: Open Next Panel View', nls.localize('view', "View"));
|
||||
|
||||
MenuRegistry.appendMenuItem(MenuId.MenubarAppearanceMenu, {
|
||||
group: '2_workbench_layout',
|
||||
|
||||
@@ -198,6 +198,13 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
.sort((v1, v2) => v1.order - v2.order);
|
||||
}
|
||||
|
||||
getPinnedPanels(): PanelDescriptor[] {
|
||||
const pinnedCompositeIds = this.compositeBar.getPinnedComposites().map(c => c.id);
|
||||
return this.getPanels()
|
||||
.filter(p => pinnedCompositeIds.indexOf(p.id) !== -1)
|
||||
.sort((p1, p2) => pinnedCompositeIds.indexOf(p1.id) - pinnedCompositeIds.indexOf(p2.id));
|
||||
}
|
||||
|
||||
setPanelEnablement(id: string, enabled: boolean): void {
|
||||
const descriptor = Registry.as<PanelRegistry>(PanelExtensions.Panels).getPanels().filter(p => p.id === id).pop();
|
||||
if (descriptor && descriptor.enabled !== enabled) {
|
||||
|
||||
@@ -767,7 +767,7 @@ export class Workbench extends Disposable implements IPartService {
|
||||
|
||||
return {
|
||||
customKeybindingsCount: this.keybindingService.customKeybindingsCount(),
|
||||
pinnedViewlets: this.activitybarPart.getPinned(),
|
||||
pinnedViewlets: this.activitybarPart.getPinnedViewletIds(),
|
||||
restoredViewlet: viewletIdToRestore,
|
||||
restoredEditorsCount: this.editorService.visibleEditors.length
|
||||
};
|
||||
|
||||
@@ -26,4 +26,9 @@ export class ActivityService implements IActivityService {
|
||||
|
||||
return this.activitybarPart.showActivity(compositeOrActionId, badge, clazz, priority);
|
||||
}
|
||||
|
||||
getPinnedViewletIds(): string[] {
|
||||
return this.activitybarPart.getPinnedViewletIds();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -65,4 +65,9 @@ export interface IActivityService {
|
||||
* Show activity in the panel for the given panel or in the activitybar for the given viewlet or global action.
|
||||
*/
|
||||
showActivity(compositeOrActionId: string, badge: IBadge, clazz?: string, priority?: number): IDisposable;
|
||||
|
||||
/**
|
||||
* Returns id of pinned viewlets following the visual order
|
||||
*/
|
||||
getPinnedViewletIds(): string[];
|
||||
}
|
||||
|
||||
@@ -34,10 +34,15 @@ export interface IPanelService {
|
||||
getActivePanel(): IPanel;
|
||||
|
||||
/**
|
||||
* Returns all enabled panels
|
||||
* * Returns all built-in panels following the default order (Problems - Output - Debug Console - Terminal)
|
||||
*/
|
||||
getPanels(): IPanelIdentifier[];
|
||||
|
||||
/**
|
||||
* Returns pinned panels following the visual order
|
||||
*/
|
||||
getPinnedPanels(): IPanelIdentifier[];
|
||||
|
||||
/**
|
||||
* Enables or disables a panel. Disabled panels are completly hidden from UI.
|
||||
* By default all panels are enabled.
|
||||
|
||||
@@ -77,6 +77,10 @@ class TestPanelService implements IPanelService {
|
||||
return [];
|
||||
}
|
||||
|
||||
public getPinnedPanels(): any[] {
|
||||
return [];
|
||||
}
|
||||
|
||||
public getActivePanel(): IViewlet {
|
||||
return activeViewlet;
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ export interface IViewletService {
|
||||
getViewlet(id: string): ViewletDescriptor;
|
||||
|
||||
/**
|
||||
* Returns all viewlets
|
||||
* Returns all enabled viewlets following the default order (Explorer - Search - SCM - Debug - Extensions)
|
||||
*/
|
||||
getAllViewlets(): ViewletDescriptor[];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user