Skip to content

Commit

Permalink
Allowing panel to dock at the top (microsoft#201452)
Browse files Browse the repository at this point in the history
  • Loading branch information
akshay2102 committed Mar 13, 2024
1 parent cb7ae02 commit b0e2e06
Show file tree
Hide file tree
Showing 8 changed files with 36 additions and 24 deletions.
24 changes: 13 additions & 11 deletions src/vs/workbench/browser/layout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1531,7 +1531,7 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
// Panel Size
const panelSize = this.stateModel.getRuntimeValue(LayoutStateKeys.PANEL_HIDDEN)
? this.workbenchGrid.getViewCachedVisibleSize(this.panelPartView)
: (this.stateModel.getRuntimeValue(LayoutStateKeys.PANEL_POSITION) === Position.BOTTOM ? this.workbenchGrid.getViewSize(this.panelPartView).height : this.workbenchGrid.getViewSize(this.panelPartView).width);
: ((this.stateModel.getRuntimeValue(LayoutStateKeys.PANEL_POSITION) === Position.BOTTOM || this.stateModel.getRuntimeValue(LayoutStateKeys.PANEL_POSITION) === Position.TOP) ? this.workbenchGrid.getViewSize(this.panelPartView).height : this.workbenchGrid.getViewSize(this.panelPartView).width);
this.stateModel.setInitializationValue(LayoutStateKeys.PANEL_SIZE, panelSize as number);

// Auxiliary Bar Size
Expand Down Expand Up @@ -1621,8 +1621,8 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi

this.workbenchGrid.resizeView(this.panelPartView,
{
width: viewSize.width + (this.getPanelPosition() !== Position.BOTTOM ? sizeChangePxWidth : 0),
height: viewSize.height + (this.getPanelPosition() !== Position.BOTTOM ? 0 : sizeChangePxHeight)
width: viewSize.width + ((this.getPanelPosition() !== Position.BOTTOM && this.getPanelPosition() !== Position.TOP) ? sizeChangePxWidth : 0),
height: viewSize.height + ((this.getPanelPosition() !== Position.BOTTOM && this.getPanelPosition() !== Position.TOP) ? 0 : sizeChangePxHeight)
});

break;
Expand Down Expand Up @@ -1757,8 +1757,8 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
private adjustPartPositions(sideBarPosition: Position, panelAlignment: PanelAlignment, panelPosition: Position): void {

// Move activity bar and side bars
const sideBarSiblingToEditor = panelPosition !== Position.BOTTOM || !(panelAlignment === 'center' || (sideBarPosition === Position.LEFT && panelAlignment === 'right') || (sideBarPosition === Position.RIGHT && panelAlignment === 'left'));
const auxiliaryBarSiblingToEditor = panelPosition !== Position.BOTTOM || !(panelAlignment === 'center' || (sideBarPosition === Position.RIGHT && panelAlignment === 'right') || (sideBarPosition === Position.LEFT && panelAlignment === 'left'));
const sideBarSiblingToEditor = (panelPosition !== Position.BOTTOM && panelPosition !== Position.TOP) || !(panelAlignment === 'center' || (sideBarPosition === Position.LEFT && panelAlignment === 'right') || (sideBarPosition === Position.RIGHT && panelAlignment === 'left'));
const auxiliaryBarSiblingToEditor = (panelPosition !== Position.BOTTOM && panelPosition !== Position.TOP) || !(panelAlignment === 'center' || (sideBarPosition === Position.RIGHT && panelAlignment === 'right') || (sideBarPosition === Position.LEFT && panelAlignment === 'left'));
const preMovePanelWidth = !this.isVisible(Parts.PANEL_PART) ? Sizing.Invisible(this.workbenchGrid.getViewCachedVisibleSize(this.panelPartView) ?? this.panelPartView.minimumWidth) : this.workbenchGrid.getViewSize(this.panelPartView).width;
const preMovePanelHeight = !this.isVisible(Parts.PANEL_PART) ? Sizing.Invisible(this.workbenchGrid.getViewCachedVisibleSize(this.panelPartView) ?? this.panelPartView.minimumHeight) : this.workbenchGrid.getViewSize(this.panelPartView).height;
const preMoveSideBarSize = !this.isVisible(Parts.SIDEBAR_PART) ? Sizing.Invisible(this.workbenchGrid.getViewCachedVisibleSize(this.sideBarPartView) ?? this.sideBarPartView.minimumWidth) : this.workbenchGrid.getViewSize(this.sideBarPartView).width;
Expand All @@ -1784,7 +1784,7 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi

// We moved all the side parts based on the editor and ignored the panel
// Now, we need to put the panel back in the right position when it is next to the editor
if (panelPosition !== Position.BOTTOM) {
if (panelPosition !== Position.BOTTOM && panelPosition !== Position.TOP) {
this.workbenchGrid.moveView(this.panelPartView, preMovePanelWidth, this.editorPartView, panelPosition === Position.LEFT ? Direction.Left : Direction.Right);
this.workbenchGrid.resizeView(this.panelPartView, {
height: preMovePanelHeight as number,
Expand Down Expand Up @@ -2086,9 +2086,9 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
// Save the current size of the panel for the new orthogonal direction
// If moving down, save the width of the panel
// Otherwise, save the height of the panel
if (position === Position.BOTTOM) {
if (position === Position.BOTTOM || position === Position.TOP) {
this.stateModel.setRuntimeValue(LayoutStateKeys.PANEL_LAST_NON_MAXIMIZED_WIDTH, size.width);
} else if (positionFromString(oldPositionValue) === Position.BOTTOM) {
} else if (positionFromString(oldPositionValue) === Position.BOTTOM || positionFromString(oldPositionValue) === Position.TOP) {
this.stateModel.setRuntimeValue(LayoutStateKeys.PANEL_LAST_NON_MAXIMIZED_HEIGHT, size.height);
}
}
Expand All @@ -2107,6 +2107,8 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
this.workbenchGrid.moveView(this.panelPartView, editorHidden ? size.height : this.stateModel.getRuntimeValue(LayoutStateKeys.PANEL_LAST_NON_MAXIMIZED_HEIGHT), this.editorPartView, Direction.Down);
} else if (position === Position.RIGHT) {
this.workbenchGrid.moveView(this.panelPartView, editorHidden ? size.width : this.stateModel.getRuntimeValue(LayoutStateKeys.PANEL_LAST_NON_MAXIMIZED_WIDTH), this.editorPartView, Direction.Right);
} else if (position === Position.TOP) {
this.workbenchGrid.moveView(this.panelPartView, editorHidden ? size.height : this.stateModel.getRuntimeValue(LayoutStateKeys.PANEL_LAST_NON_MAXIMIZED_HEIGHT), this.editorPartView, Direction.Up);
} else {
this.workbenchGrid.moveView(this.panelPartView, editorHidden ? size.width : this.stateModel.getRuntimeValue(LayoutStateKeys.PANEL_LAST_NON_MAXIMIZED_WIDTH), this.editorPartView, Direction.Left);
}
Expand All @@ -2122,7 +2124,7 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
this.setAuxiliaryBarHidden(true);
}

if (position === Position.BOTTOM) {
if (position === Position.BOTTOM || position === Position.TOP) {
this.adjustPartPositions(this.getSideBarPosition(), this.getPanelAlignment(), position);
}

Expand Down Expand Up @@ -2232,7 +2234,7 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
const panelSize = this.stateModel.getInitializationValue(LayoutStateKeys.PANEL_SIZE) ? 0 : nodes.panel.size;

const result = [] as ISerializedNode[];
if (this.stateModel.getRuntimeValue(LayoutStateKeys.PANEL_POSITION) !== Position.BOTTOM) {
if (this.stateModel.getRuntimeValue(LayoutStateKeys.PANEL_POSITION) !== Position.BOTTOM && this.stateModel.getRuntimeValue(LayoutStateKeys.PANEL_POSITION) !== Position.TOP) {
result.push(nodes.editor);
nodes.editor.size = availableWidth - activityBarSize - sideBarSize - panelSize - auxiliaryBarSize;
if (this.stateModel.getRuntimeValue(LayoutStateKeys.PANEL_POSITION) === Position.RIGHT) {
Expand Down Expand Up @@ -2617,7 +2619,7 @@ class LayoutStateModel extends Disposable {
LayoutStateKeys.GRID_SIZE.defaultValue = { height: workbenchDimensions.height, width: workbenchDimensions.width };
LayoutStateKeys.SIDEBAR_SIZE.defaultValue = Math.min(300, workbenchDimensions.width / 4);
LayoutStateKeys.AUXILIARYBAR_SIZE.defaultValue = Math.min(300, workbenchDimensions.width / 4);
LayoutStateKeys.PANEL_SIZE.defaultValue = (this.stateCache.get(LayoutStateKeys.PANEL_POSITION.name) ?? LayoutStateKeys.PANEL_POSITION.defaultValue) === Position.BOTTOM ? workbenchDimensions.height / 3 : workbenchDimensions.width / 4;
LayoutStateKeys.PANEL_SIZE.defaultValue = (this.stateCache.get(LayoutStateKeys.PANEL_POSITION.name) ?? (LayoutStateKeys.PANEL_POSITION.defaultValue === Position.BOTTOM || LayoutStateKeys.PANEL_POSITION.defaultValue === Position.TOP)) ? workbenchDimensions.height / 3 : workbenchDimensions.width / 4;
LayoutStateKeys.SIDEBAR_HIDDEN.defaultValue = this.contextService.getWorkbenchState() === WorkbenchState.EMPTY;

// Apply all defaults
Expand Down
8 changes: 6 additions & 2 deletions src/vs/workbench/browser/parts/editor/editorPart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1098,6 +1098,10 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupsView {
openVerticalPosition = Position.BOTTOM;
}

if (e.eventData.clientY < boundingRect.top + proximity) {
openVerticalPosition = Position.TOP;
}

if (horizontalOpenerTimeout && openHorizontalPosition !== lastOpenHorizontalPosition) {
clearTimeout(horizontalOpenerTimeout);
horizontalOpenerTimeout = undefined;
Expand All @@ -1110,12 +1114,12 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupsView {

if (!horizontalOpenerTimeout && openHorizontalPosition !== undefined) {
lastOpenHorizontalPosition = openHorizontalPosition;
horizontalOpenerTimeout = setTimeout(() => openPartAtPosition(openHorizontalPosition), 200);
horizontalOpenerTimeout = setTimeout(() => openPartAtPosition(openHorizontalPosition!), 200);
}

if (!verticalOpenerTimeout && openVerticalPosition !== undefined) {
lastOpenVerticalPosition = openVerticalPosition;
verticalOpenerTimeout = setTimeout(() => openPartAtPosition(openVerticalPosition), 200);
verticalOpenerTimeout = setTimeout(() => openPartAtPosition(openVerticalPosition!), 200);
}
},
onDragLeave: () => clearAllTimeouts(),
Expand Down
2 changes: 2 additions & 0 deletions src/vs/workbench/browser/parts/panel/panelActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ const PositionPanelActionId = {
LEFT: 'workbench.action.positionPanelLeft',
RIGHT: 'workbench.action.positionPanelRight',
BOTTOM: 'workbench.action.positionPanelBottom',
TOP: 'workbench.action.positionPanelTop'
};

const AlignPanelActionId = {
Expand Down Expand Up @@ -139,6 +140,7 @@ const PositionPanelActionConfigs: PanelActionConfig<Position>[] = [
createPositionPanelActionConfig(PositionPanelActionId.LEFT, localize2('positionPanelLeft', "Move Panel Left"), localize('positionPanelLeftShort', "Left"), Position.LEFT),
createPositionPanelActionConfig(PositionPanelActionId.RIGHT, localize2('positionPanelRight', "Move Panel Right"), localize('positionPanelRightShort', "Right"), Position.RIGHT),
createPositionPanelActionConfig(PositionPanelActionId.BOTTOM, localize2('positionPanelBottom', "Move Panel To Bottom"), localize('positionPanelBottomShort', "Bottom"), Position.BOTTOM),
createPositionPanelActionConfig(PositionPanelActionId.TOP, localize2('positionPanelTop', "Move Panel To Top"), localize('positionPanelTopShort', "Top"), Position.TOP)
];


Expand Down
2 changes: 1 addition & 1 deletion src/vs/workbench/browser/parts/views/viewPaneContainer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -620,7 +620,7 @@ export class ViewPaneContainer extends Component implements IViewPaneContainer {
case ViewContainerLocation.AuxiliaryBar:
return Orientation.VERTICAL;
case ViewContainerLocation.Panel:
return this.layoutService.getPanelPosition() === Position.BOTTOM ? Orientation.HORIZONTAL : Orientation.VERTICAL;
return (this.layoutService.getPanelPosition() === Position.BOTTOM || this.layoutService.getPanelPosition() === Position.TOP) ? Orientation.HORIZONTAL : Orientation.VERTICAL;
}

return Orientation.VERTICAL;
Expand Down
4 changes: 2 additions & 2 deletions src/vs/workbench/browser/workbench.contribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -475,9 +475,9 @@ const registry = Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Con
},
'workbench.panel.defaultLocation': {
'type': 'string',
'enum': ['left', 'bottom', 'right'],
'enum': ['left', 'bottom', 'top', 'right'],
'default': 'bottom',
'description': localize('panelDefaultLocation', "Controls the default location of the panel (Terminal, Debug Console, Output, Problems) in a new workspace. It can either show at the bottom, right, or left of the editor area."),
'description': localize('panelDefaultLocation', "Controls the default location of the panel (Terminal, Debug Console, Output, Problems) in a new workspace. It can either show at the bottom, top, right, or left of the editor area."),
},
'workbench.panel.opensMaximized': {
'type': 'string',
Expand Down
11 changes: 6 additions & 5 deletions src/vs/workbench/contrib/terminal/browser/terminalGroup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ export class TerminalGroup extends Disposable implements ITerminalGroup {
if (this._container) {
this.attachToElement(this._container);
}
this._onPanelOrientationChanged.fire(this._terminalLocation === ViewContainerLocation.Panel && this._panelPosition === Position.BOTTOM ? Orientation.HORIZONTAL : Orientation.VERTICAL);
this._onPanelOrientationChanged.fire(this._terminalLocation === ViewContainerLocation.Panel && (this._panelPosition === Position.BOTTOM || this._panelPosition === Position.TOP) ? Orientation.HORIZONTAL : Orientation.VERTICAL);
this._register(toDisposable(() => {
if (this._container && this._groupElement) {
this._container.removeChild(this._groupElement);
Expand Down Expand Up @@ -466,7 +466,7 @@ export class TerminalGroup extends Disposable implements ITerminalGroup {
if (!this._splitPaneContainer) {
this._panelPosition = this._layoutService.getPanelPosition();
this._terminalLocation = this._viewDescriptorService.getViewLocationById(TERMINAL_VIEW_ID)!;
const orientation = this._terminalLocation === ViewContainerLocation.Panel && this._panelPosition === Position.BOTTOM ? Orientation.HORIZONTAL : Orientation.VERTICAL;
const orientation = this._terminalLocation === ViewContainerLocation.Panel && (this._panelPosition === Position.BOTTOM || this._panelPosition === Position.TOP) ? Orientation.HORIZONTAL : Orientation.VERTICAL;
this._splitPaneContainer = this._instantiationService.createInstance(SplitPaneContainer, this._groupElement, orientation);
this.terminalInstances.forEach(instance => this._splitPaneContainer!.split(instance, this._activeInstanceIndex + 1));
}
Expand Down Expand Up @@ -527,7 +527,7 @@ export class TerminalGroup extends Disposable implements ITerminalGroup {
const newTerminalLocation = this._viewDescriptorService.getViewLocationById(TERMINAL_VIEW_ID)!;
const terminalPositionChanged = newPanelPosition !== this._panelPosition || newTerminalLocation !== this._terminalLocation;
if (terminalPositionChanged) {
const newOrientation = newTerminalLocation === ViewContainerLocation.Panel && newPanelPosition === Position.BOTTOM ? Orientation.HORIZONTAL : Orientation.VERTICAL;
const newOrientation = newTerminalLocation === ViewContainerLocation.Panel && (newPanelPosition === Position.BOTTOM || newPanelPosition === Position.TOP) ? Orientation.HORIZONTAL : Orientation.VERTICAL;
this._splitPaneContainer.setOrientation(newOrientation);
this._panelPosition = newPanelPosition;
this._terminalLocation = newTerminalLocation;
Expand Down Expand Up @@ -563,7 +563,7 @@ export class TerminalGroup extends Disposable implements ITerminalGroup {
}

private _getOrientation(): Orientation {
return this._getPosition() === Position.BOTTOM ? Orientation.HORIZONTAL : Orientation.VERTICAL;
return (this._getPosition() === Position.BOTTOM || this._getPosition() === Position.TOP) ? Orientation.HORIZONTAL : Orientation.VERTICAL;
}

resizePane(direction: Direction): void {
Expand Down Expand Up @@ -591,7 +591,8 @@ export class TerminalGroup extends Disposable implements ITerminalGroup {
const shouldShrink =
(this._getPosition() === Position.LEFT && direction === Direction.Left) ||
(this._getPosition() === Position.RIGHT && direction === Direction.Right) ||
(this._getPosition() === Position.BOTTOM && direction === Direction.Down);
(this._getPosition() === Position.BOTTOM && direction === Direction.Down) ||
(this._getPosition() === Position.TOP && direction === Direction.Up);

if (shouldShrink) {
resizeAmount *= -1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2357,7 +2357,7 @@ class TerminalInstanceDragAndDropController extends Disposable implements dom.ID
private _getViewOrientation(): Orientation {
const panelPosition = this._layoutService.getPanelPosition();
const terminalLocation = this._viewDescriptorService.getViewLocationById(TERMINAL_VIEW_ID);
return terminalLocation === ViewContainerLocation.Panel && panelPosition === Position.BOTTOM
return terminalLocation === ViewContainerLocation.Panel && (panelPosition === Position.BOTTOM || panelPosition === Position.TOP)
? Orientation.HORIZONTAL
: Orientation.VERTICAL;
}
Expand Down
7 changes: 5 additions & 2 deletions src/vs/workbench/services/layout/browser/layoutService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ export const enum EditorActionsLocation {
export const enum Position {
LEFT,
RIGHT,
BOTTOM
BOTTOM,
TOP
}

export const enum PanelOpensMaximizedOptions {
Expand All @@ -86,14 +87,16 @@ export function positionToString(position: Position): string {
case Position.LEFT: return 'left';
case Position.RIGHT: return 'right';
case Position.BOTTOM: return 'bottom';
case Position.TOP: return 'top';
default: return 'bottom';
}
}

const positionsByString: { [key: string]: Position } = {
[positionToString(Position.LEFT)]: Position.LEFT,
[positionToString(Position.RIGHT)]: Position.RIGHT,
[positionToString(Position.BOTTOM)]: Position.BOTTOM
[positionToString(Position.BOTTOM)]: Position.BOTTOM,
[positionToString(Position.TOP)]: Position.TOP
};

export function positionFromString(str: string): Position {
Expand Down

0 comments on commit b0e2e06

Please sign in to comment.