Skip to content

Commit 83b1a1c

Browse files
committed
splitview: use TLayoutContext
gridview: propagate top, left in layout
1 parent fd16e7c commit 83b1a1c

5 files changed

Lines changed: 90 additions & 58 deletions

File tree

src/vs/base/browser/ui/centered/centeredViewLayout.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ function toSplitViewView(view: IView, getHeight: () => number): ISplitViewView {
4242
get maximumSize() { return view.maximumWidth; },
4343
get minimumSize() { return view.minimumWidth; },
4444
onDidChange: Event.map(view.onDidChange, e => e && e.width),
45-
layout: size => view.layout(size, getHeight())
45+
layout: (size, offset) => view.layout(size, getHeight(), 0, offset)
4646
};
4747
}
4848

@@ -81,7 +81,7 @@ export class CenteredViewLayout implements IDisposable {
8181
this.resizeMargins();
8282
}
8383
} else {
84-
this.view.layout(width, height);
84+
this.view.layout(width, height, 0, 0);
8585
}
8686
this.didLayout = true;
8787
}

src/vs/base/browser/ui/grid/gridview.ts

Lines changed: 45 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export interface IView {
3030
readonly onDidChange: Event<IViewSize | undefined>;
3131
readonly priority?: LayoutPriority;
3232
readonly snap?: boolean;
33-
layout(width: number, height: number): void;
33+
layout(width: number, height: number, top: number, left: number): void;
3434
setVisible?(visible: boolean): void;
3535
}
3636

@@ -117,18 +117,29 @@ export interface IGridViewOptions {
117117
readonly layoutController?: ILayoutController;
118118
}
119119

120-
class BranchNode implements ISplitView, IDisposable {
120+
interface ILayoutContext {
121+
readonly orthogonalSize: number;
122+
readonly orthogonalOffset: number;
123+
}
124+
125+
class BranchNode implements ISplitView<ILayoutContext>, IDisposable {
121126

122127
readonly element: HTMLElement;
123128
readonly children: Node[] = [];
124-
private splitview: SplitView;
129+
private splitview: SplitView<ILayoutContext>;
125130

126131
private _size: number;
127132
get size(): number { return this._size; }
128133

129134
private _orthogonalSize: number;
130135
get orthogonalSize(): number { return this._orthogonalSize; }
131136

137+
private _offset: number = 0;
138+
get offset(): number { return this._offset; }
139+
140+
private _orthogonalOffset: number = 0;
141+
get orthogonalOffset(): number { return this._orthogonalOffset; }
142+
132143
private _styles: IGridViewStyles;
133144
get styles(): IGridViewStyles { return this._styles; }
134145

@@ -221,7 +232,7 @@ class BranchNode implements ISplitView, IDisposable {
221232
if (!childDescriptors) {
222233
// Normal behavior, we have no children yet, just set up the splitview
223234
this.splitview = new SplitView(this.element, { orientation, styles, proportionalLayout });
224-
this.splitview.layout(size, orthogonalSize);
235+
this.splitview.layout(size, { orthogonalSize, orthogonalOffset: 0 });
225236
} else {
226237
// Reconstruction behavior, we want to reconstruct a splitview
227238
const descriptor = {
@@ -268,20 +279,23 @@ class BranchNode implements ISplitView, IDisposable {
268279
}
269280
}
270281

271-
layout(size: number, orthogonalSize: number | undefined): void {
282+
layout(size: number, offset: number, ctx: ILayoutContext | undefined): void {
272283
if (!this.layoutController.isLayoutEnabled) {
273284
return;
274285
}
275286

276-
if (typeof orthogonalSize !== 'number') {
287+
if (typeof ctx === 'undefined') {
277288
throw new Error('Invalid state');
278289
}
279290

280291
// branch nodes should flip the normal/orthogonal directions
281-
this._size = orthogonalSize;
292+
this._size = ctx.orthogonalSize;
282293
this._orthogonalSize = size;
283294

284-
this.splitview.layout(orthogonalSize, size);
295+
this.splitview.layout(ctx.orthogonalSize, {
296+
orthogonalSize: size,
297+
orthogonalOffset: offset
298+
});
285299
}
286300

287301
setVisible(visible: boolean): void {
@@ -511,14 +525,20 @@ class BranchNode implements ISplitView, IDisposable {
511525
}
512526
}
513527

514-
class LeafNode implements ISplitView, IDisposable {
528+
class LeafNode implements ISplitView<ILayoutContext>, IDisposable {
515529

516530
private _size: number = 0;
517531
get size(): number { return this._size; }
518532

519533
private _orthogonalSize: number;
520534
get orthogonalSize(): number { return this._orthogonalSize; }
521535

536+
private _offset: number = 0;
537+
get offset(): number { return this._offset; }
538+
539+
private _orthogonalOffset: number = 0;
540+
get orthogonalOffset(): number { return this._orthogonalOffset; }
541+
522542
readonly onDidSashReset: Event<number[]> = Event.None;
523543

524544
private _onDidLinkedWidthNodeChange = new Relay<number | undefined>();
@@ -565,6 +585,14 @@ class LeafNode implements ISplitView, IDisposable {
565585
return this.orientation === Orientation.HORIZONTAL ? this.size : this.orthogonalSize;
566586
}
567587

588+
get top(): number {
589+
return this.orientation === Orientation.HORIZONTAL ? this.offset : this.orthogonalOffset;
590+
}
591+
592+
get left(): number {
593+
return this.orientation === Orientation.HORIZONTAL ? this.orthogonalOffset : this.offset;
594+
}
595+
568596
get element(): HTMLElement {
569597
return this.view.element;
570598
}
@@ -617,18 +645,20 @@ class LeafNode implements ISplitView, IDisposable {
617645
// noop
618646
}
619647

620-
layout(size: number, orthogonalSize: number | undefined): void {
648+
layout(size: number, offset: number, ctx: ILayoutContext | undefined): void {
621649
if (!this.layoutController.isLayoutEnabled) {
622650
return;
623651
}
624652

625-
if (typeof orthogonalSize !== 'number') {
653+
if (typeof ctx === 'undefined') {
626654
throw new Error('Invalid state');
627655
}
628656

629657
this._size = size;
630-
this._orthogonalSize = orthogonalSize;
631-
this.view.layout(this.width, this.height);
658+
this._offset = offset;
659+
this._orthogonalSize = ctx.orthogonalSize;
660+
this._orthogonalOffset = ctx.orthogonalOffset;
661+
this.view.layout(this.width, this.height, this.top, this.left);
632662
}
633663

634664
setVisible(visible: boolean): void {
@@ -715,7 +745,7 @@ export class GridView implements IDisposable {
715745

716746
const { size, orthogonalSize } = this._root;
717747
this.root = flipNode(this._root, orthogonalSize, size);
718-
this.root.layout(size, orthogonalSize);
748+
this.root.layout(size, 0, { orthogonalSize, orthogonalOffset: 0 });
719749
}
720750

721751
get width(): number { return this.root.width; }
@@ -771,7 +801,7 @@ export class GridView implements IDisposable {
771801
this.firstLayoutController.isLayoutEnabled = true;
772802

773803
const [size, orthogonalSize] = this.root.orientation === Orientation.HORIZONTAL ? [height, width] : [width, height];
774-
this.root.layout(size, orthogonalSize);
804+
this.root.layout(size, 0, { orthogonalSize, orthogonalOffset: 0 });
775805
}
776806

777807
addView(view: IView, size: number | Sizing, location: number[]): void {

src/vs/base/browser/ui/splitview/splitview.ts

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,14 @@ const defaultStyles: ISplitViewStyles = {
2323
separatorBorder: Color.transparent
2424
};
2525

26-
export interface ISplitViewOptions {
26+
export interface ISplitViewOptions<TLayoutContext = undefined> {
2727
readonly orientation?: Orientation; // default Orientation.VERTICAL
2828
readonly styles?: ISplitViewStyles;
2929
readonly orthogonalStartSash?: Sash;
3030
readonly orthogonalEndSash?: Sash;
3131
readonly inverseAltBehavior?: boolean;
3232
readonly proportionalLayout?: boolean; // default true,
33-
readonly descriptor?: ISplitViewDescriptor;
33+
readonly descriptor?: ISplitViewDescriptor<TLayoutContext>;
3434
}
3535

3636
/**
@@ -42,14 +42,14 @@ export const enum LayoutPriority {
4242
High
4343
}
4444

45-
export interface IView {
45+
export interface IView<TLayoutContext = undefined> {
4646
readonly element: HTMLElement;
4747
readonly minimumSize: number;
4848
readonly maximumSize: number;
4949
readonly onDidChange: Event<number | undefined>;
5050
readonly priority?: LayoutPriority;
5151
readonly snap?: boolean;
52-
layout(size: number, orthogonalSize: number | undefined): void;
52+
layout(size: number, offset: number, context: TLayoutContext | undefined): void;
5353
setVisible?(visible: boolean): void;
5454
}
5555

@@ -62,7 +62,7 @@ interface ISashEvent {
6262

6363
type ViewItemSize = number | { cachedVisibleSize: number };
6464

65-
abstract class ViewItem {
65+
abstract class ViewItem<TLayoutContext> {
6666

6767
private _size: number;
6868
set size(size: number) {
@@ -115,7 +115,7 @@ abstract class ViewItem {
115115

116116
constructor(
117117
protected container: HTMLElement,
118-
private view: IView,
118+
private view: IView<TLayoutContext>,
119119
size: ViewItemSize,
120120
private disposable: IDisposable
121121
) {
@@ -129,31 +129,31 @@ abstract class ViewItem {
129129
}
130130
}
131131

132-
layout(position: number, orthogonalSize: number | undefined): void {
133-
this.layoutContainer(position);
134-
this.view.layout(this.size, orthogonalSize);
132+
layout(offset: number, layoutContext: TLayoutContext | undefined): void {
133+
this.layoutContainer(offset);
134+
this.view.layout(this.size, offset, layoutContext);
135135
}
136136

137-
abstract layoutContainer(position: number): void;
137+
abstract layoutContainer(offset: number): void;
138138

139-
dispose(): IView {
139+
dispose(): IView<TLayoutContext> {
140140
this.disposable.dispose();
141141
return this.view;
142142
}
143143
}
144144

145-
class VerticalViewItem extends ViewItem {
145+
class VerticalViewItem<TLayoutContext> extends ViewItem<TLayoutContext> {
146146

147-
layoutContainer(position: number): void {
148-
this.container.style.top = `${position}px`;
147+
layoutContainer(offset: number): void {
148+
this.container.style.top = `${offset}px`;
149149
this.container.style.height = `${this.size}px`;
150150
}
151151
}
152152

153-
class HorizontalViewItem extends ViewItem {
153+
class HorizontalViewItem<TLayoutContext> extends ViewItem<TLayoutContext> {
154154

155-
layoutContainer(position: number): void {
156-
this.container.style.left = `${position}px`;
155+
layoutContainer(offset: number): void {
156+
this.container.style.left = `${offset}px`;
157157
this.container.style.width = `${this.size}px`;
158158
}
159159
}
@@ -198,26 +198,26 @@ export namespace Sizing {
198198
export function Invisible(cachedVisibleSize: number): InvisibleSizing { return { type: 'invisible', cachedVisibleSize }; }
199199
}
200200

201-
export interface ISplitViewDescriptor {
201+
export interface ISplitViewDescriptor<TLayoutContext> {
202202
size: number;
203203
views: {
204204
visible?: boolean;
205205
size: number;
206-
view: IView;
206+
view: IView<TLayoutContext>;
207207
}[];
208208
}
209209

210-
export class SplitView extends Disposable {
210+
export class SplitView<TLayoutContext = undefined> extends Disposable {
211211

212212
readonly orientation: Orientation;
213213
readonly el: HTMLElement;
214214
private sashContainer: HTMLElement;
215215
private viewContainer: HTMLElement;
216216
private size = 0;
217-
private orthogonalSize: number | undefined;
217+
private layoutContext: TLayoutContext | undefined;
218218
private contentSize = 0;
219219
private proportions: undefined | number[] = undefined;
220-
private viewItems: ViewItem[] = [];
220+
private viewItems: ViewItem<TLayoutContext>[] = [];
221221
private sashItems: ISashItem[] = [];
222222
private sashDragState: ISashDragState | undefined;
223223
private state: State = State.Idle;
@@ -280,7 +280,7 @@ export class SplitView extends Disposable {
280280
this.updateSashEnablement();
281281
}
282282

283-
constructor(container: HTMLElement, options: ISplitViewOptions = {}) {
283+
constructor(container: HTMLElement, options: ISplitViewOptions<TLayoutContext> = {}) {
284284
super();
285285

286286
this.orientation = types.isUndefined(options.orientation) ? Orientation.VERTICAL : options.orientation;
@@ -323,11 +323,11 @@ export class SplitView extends Disposable {
323323
}
324324
}
325325

326-
addView(view: IView, size: number | Sizing, index = this.viewItems.length): void {
326+
addView(view: IView<TLayoutContext>, size: number | Sizing, index = this.viewItems.length): void {
327327
this.doAddView(view, size, index, false);
328328
}
329329

330-
removeView(index: number, sizing?: Sizing): IView {
330+
removeView(index: number, sizing?: Sizing): IView<TLayoutContext> {
331331
if (this.state !== State.Idle) {
332332
throw new Error('Cant modify splitview');
333333
}
@@ -419,10 +419,10 @@ export class SplitView extends Disposable {
419419
return viewItem.cachedVisibleSize;
420420
}
421421

422-
layout(size: number, orthogonalSize?: number): void {
422+
layout(size: number, layoutContext?: TLayoutContext): void {
423423
const previousSize = Math.max(this.size, this.contentSize);
424424
this.size = size;
425-
this.orthogonalSize = orthogonalSize;
425+
this.layoutContext = layoutContext;
426426

427427
if (!this.proportions) {
428428
const indexes = range(this.viewItems.length);
@@ -563,7 +563,7 @@ export class SplitView extends Disposable {
563563
}
564564
}
565565

566-
private onViewChange(item: ViewItem, size: number | undefined): void {
566+
private onViewChange(item: ViewItem<TLayoutContext>, size: number | undefined): void {
567567
const index = this.viewItems.indexOf(item);
568568

569569
if (index < 0 || index >= this.viewItems.length) {
@@ -610,7 +610,7 @@ export class SplitView extends Disposable {
610610
}
611611

612612
distributeViewSizes(): void {
613-
const flexibleViewItems: ViewItem[] = [];
613+
const flexibleViewItems: ViewItem<TLayoutContext>[] = [];
614614
let flexibleSize = 0;
615615

616616
for (const item of this.viewItems) {
@@ -641,7 +641,7 @@ export class SplitView extends Disposable {
641641
return this.viewItems[index].size;
642642
}
643643

644-
private doAddView(view: IView, size: number | Sizing, index = this.viewItems.length, skipLayout?: boolean): void {
644+
private doAddView(view: IView<TLayoutContext>, size: number | Sizing, index = this.viewItems.length, skipLayout?: boolean): void {
645645
if (this.state !== State.Idle) {
646646
throw new Error('Cant modify splitview');
647647
}
@@ -875,11 +875,11 @@ export class SplitView extends Disposable {
875875
this.contentSize = this.viewItems.reduce((r, i) => r + i.size, 0);
876876

877877
// Layout views
878-
let position = 0;
878+
let offset = 0;
879879

880880
for (const viewItem of this.viewItems) {
881-
viewItem.layout(position, this.orthogonalSize);
882-
position += viewItem.size;
881+
viewItem.layout(offset, this.layoutContext);
882+
offset += viewItem.size;
883883
}
884884

885885
// Layout sashes

0 commit comments

Comments
 (0)