Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/sessions/browser/parts/panelPart.ts
13395 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import '../../../workbench/browser/parts/panel/media/panelpart.css';
7
import './media/panelPart.css';
8
import { IAction } from '../../../base/common/actions.js';
9
import { ActionsOrientation } from '../../../base/browser/ui/actionbar/actionbar.js';
10
import { ActivePanelContext, PanelFocusContext } from '../../../workbench/common/contextkeys.js';
11
import { IWorkbenchLayoutService, Parts, Position } from '../../../workbench/services/layout/browser/layoutService.js';
12
import { IStorageService } from '../../../platform/storage/common/storage.js';
13
import { IContextMenuService } from '../../../platform/contextview/browser/contextView.js';
14
import { IKeybindingService } from '../../../platform/keybinding/common/keybinding.js';
15
import { IInstantiationService } from '../../../platform/instantiation/common/instantiation.js';
16
import { IThemeService } from '../../../platform/theme/common/themeService.js';
17
import { PANEL_TITLE_BORDER, PANEL_ACTIVE_TITLE_FOREGROUND, PANEL_INACTIVE_TITLE_FOREGROUND, PANEL_ACTIVE_TITLE_BORDER, PANEL_DRAG_AND_DROP_BORDER } from '../../../workbench/common/theme.js';
18
import { agentsBadgeBackground, agentsBadgeForeground, agentsPanelBackground, agentsPanelBorder, agentsPanelForeground } from '../../common/theme.js';
19
import { INotificationService } from '../../../platform/notification/common/notification.js';
20
import { IContextKeyService } from '../../../platform/contextkey/common/contextkey.js';
21
import { assertReturnsDefined } from '../../../base/common/types.js';
22
import { IExtensionService } from '../../../workbench/services/extensions/common/extensions.js';
23
import { IViewDescriptorService, ViewContainerLocation } from '../../../workbench/common/views.js';
24
import { HoverPosition } from '../../../base/browser/ui/hover/hoverWidget.js';
25
import { IMenuService } from '../../../platform/actions/common/actions.js';
26
import { Menus } from '../menus.js';
27
import { AbstractPaneCompositePart, CompositeBarPosition } from '../../../workbench/browser/parts/paneCompositePart.js';
28
import { Part } from '../../../workbench/browser/part.js';
29
import { IPaneCompositeBarOptions } from '../../../workbench/browser/parts/paneCompositeBar.js';
30
import { IHoverService } from '../../../platform/hover/browser/hover.js';
31
import { IConfigurationService } from '../../../platform/configuration/common/configuration.js';
32
import { Extensions } from '../../../workbench/browser/panecomposite.js';
33
34
/**
35
* Panel part specifically for agent sessions workbench.
36
* This is a simplified version of the PanelPart for agent session contexts.
37
*/
38
export class PanelPart extends AbstractPaneCompositePart {
39
40
//#region IView
41
42
readonly minimumWidth: number = 300;
43
readonly maximumWidth: number = Number.POSITIVE_INFINITY;
44
readonly minimumHeight: number = 77;
45
readonly maximumHeight: number = Number.POSITIVE_INFINITY;
46
47
get preferredHeight(): number | undefined {
48
return this.layoutService.mainContainerDimension.height * 0.4;
49
}
50
51
get preferredWidth(): number | undefined {
52
const activeComposite = this.getActivePaneComposite();
53
54
if (!activeComposite) {
55
return undefined;
56
}
57
58
const width = activeComposite.getOptimalWidth();
59
if (typeof width !== 'number') {
60
return undefined;
61
}
62
63
return Math.max(width, 300);
64
}
65
66
//#endregion
67
68
static readonly activePanelSettingsKey = 'workbench.agentsession.panelpart.activepanelid';
69
70
/** Visual margin values for the card-like appearance */
71
static readonly MARGIN_BOTTOM = 10;
72
static readonly MARGIN_LEFT = 10;
73
static readonly MARGIN_RIGHT = 10;
74
75
constructor(
76
@INotificationService notificationService: INotificationService,
77
@IStorageService storageService: IStorageService,
78
@IContextMenuService contextMenuService: IContextMenuService,
79
@IWorkbenchLayoutService layoutService: IWorkbenchLayoutService,
80
@IKeybindingService keybindingService: IKeybindingService,
81
@IHoverService hoverService: IHoverService,
82
@IInstantiationService instantiationService: IInstantiationService,
83
@IThemeService themeService: IThemeService,
84
@IViewDescriptorService viewDescriptorService: IViewDescriptorService,
85
@IContextKeyService contextKeyService: IContextKeyService,
86
@IExtensionService extensionService: IExtensionService,
87
@IMenuService menuService: IMenuService,
88
@IConfigurationService private readonly configurationService: IConfigurationService
89
) {
90
super(
91
Parts.PANEL_PART,
92
{ hasTitle: true, trailingSeparator: true },
93
PanelPart.activePanelSettingsKey,
94
ActivePanelContext.bindTo(contextKeyService),
95
PanelFocusContext.bindTo(contextKeyService),
96
'panel',
97
'panel',
98
undefined,
99
PANEL_TITLE_BORDER,
100
ViewContainerLocation.Panel,
101
Extensions.Panels,
102
Menus.PanelTitle,
103
notificationService,
104
storageService,
105
contextMenuService,
106
layoutService,
107
keybindingService,
108
hoverService,
109
instantiationService,
110
themeService,
111
viewDescriptorService,
112
contextKeyService,
113
extensionService,
114
menuService,
115
);
116
117
this._register(this.configurationService.onDidChangeConfiguration(e => {
118
if (e.affectsConfiguration('workbench.panel.showLabels')) {
119
this.updateCompositeBar(true);
120
}
121
}));
122
}
123
124
override updateStyles(): void {
125
super.updateStyles();
126
127
const container = assertReturnsDefined(this.getContainer());
128
129
// Store background and border as CSS variables for the card styling on .part
130
container.style.setProperty('--part-background', this.getColor(agentsPanelBackground) || '');
131
container.style.setProperty('--part-border-color', this.getColor(agentsPanelBorder) || 'transparent');
132
container.style.setProperty('--part-foreground', this.getColor(agentsPanelForeground) || '');
133
container.style.backgroundColor = this.getColor(agentsPanelBackground) || '';
134
135
// Clear inline borders - the card appearance uses CSS border-radius instead
136
container.style.borderTopColor = '';
137
container.style.borderTopStyle = '';
138
container.style.borderTopWidth = '';
139
}
140
141
protected getCompositeBarOptions(): IPaneCompositeBarOptions {
142
return {
143
partContainerClass: 'panel',
144
pinnedViewContainersKey: 'workbench.agentsession.panel.pinnedPanels',
145
placeholderViewContainersKey: 'workbench.agentsession.panel.placeholderPanels',
146
viewContainersWorkspaceStateKey: 'workbench.agentsession.panel.viewContainersWorkspaceState',
147
icon: this.configurationService.getValue('workbench.panel.showLabels') === false,
148
orientation: ActionsOrientation.HORIZONTAL,
149
recomputeSizes: true,
150
activityHoverOptions: {
151
position: () => this.layoutService.getPanelPosition() === Position.BOTTOM && !this.layoutService.isPanelMaximized() ? HoverPosition.ABOVE : HoverPosition.BELOW,
152
},
153
fillExtraContextMenuActions: actions => this.fillExtraContextMenuActions(actions),
154
compositeSize: 0,
155
iconSize: 16,
156
compact: true,
157
overflowActionSize: 44,
158
colors: theme => ({
159
activeBackgroundColor: theme.getColor(agentsPanelBackground),
160
inactiveBackgroundColor: theme.getColor(agentsPanelBackground),
161
activeBorderBottomColor: theme.getColor(PANEL_ACTIVE_TITLE_BORDER),
162
activeForegroundColor: theme.getColor(PANEL_ACTIVE_TITLE_FOREGROUND),
163
inactiveForegroundColor: theme.getColor(PANEL_INACTIVE_TITLE_FOREGROUND),
164
badgeBackground: theme.getColor(agentsBadgeBackground),
165
badgeForeground: theme.getColor(agentsBadgeForeground),
166
dragAndDropBorder: theme.getColor(PANEL_DRAG_AND_DROP_BORDER)
167
})
168
};
169
}
170
171
private fillExtraContextMenuActions(_actions: IAction[]): void { }
172
173
override layout(width: number, height: number, top: number, left: number): void {
174
if (!this.layoutService.isVisible(Parts.PANEL_PART)) {
175
return;
176
}
177
178
// Layout content with reduced dimensions to account for visual margins and border
179
const borderTotal = 2; // 1px border on each side
180
const marginLeft = this.layoutService.isVisible(Parts.SIDEBAR_PART) ? 0 : PanelPart.MARGIN_LEFT;
181
super.layout(
182
width - marginLeft - PanelPart.MARGIN_RIGHT - borderTotal,
183
height - PanelPart.MARGIN_BOTTOM - borderTotal,
184
top, left
185
);
186
187
// Restore the full grid-allocated dimensions so that Part.relayout() works correctly.
188
Part.prototype.layout.call(this, width, height, top, left);
189
}
190
191
protected override shouldShowCompositeBar(): boolean {
192
return true;
193
}
194
195
protected getCompositeBarPosition(): CompositeBarPosition {
196
return CompositeBarPosition.TITLE;
197
}
198
199
toJSON(): object {
200
return {
201
type: Parts.PANEL_PART
202
};
203
}
204
}
205
206