sussudio
Version:
An unofficial VS Code Internal API
416 lines (415 loc) • 13.8 kB
text/typescript
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Orientation, Sash } from "../sash/sash.mjs";
import { Color } from "../../../common/color.mjs";
import { Event } from "../../../common/event.mjs";
import { Disposable, IDisposable } from "../../../common/lifecycle.mjs";
import { ScrollbarVisibility, ScrollEvent } from "../../../common/scrollable.mjs";
import "../../../../css!./splitview.mjs";
export { Orientation } from "../sash/sash.mjs";
export interface ISplitViewStyles {
readonly separatorBorder: Color;
}
export declare const enum LayoutPriority {
Normal = 0,
Low = 1,
High = 2
}
/**
* The interface to implement for views within a {@link SplitView}.
*
* An optional {@link TLayoutContext layout context type} may be used in order to
* pass along layout contextual data from the {@link SplitView.layout} method down
* to each view's {@link IView.layout} calls.
*/
export interface IView<TLayoutContext = undefined> {
/**
* The DOM element for this view.
*/
readonly element: HTMLElement;
/**
* A minimum size for this view.
*
* @remarks If none, set it to `0`.
*/
readonly minimumSize: number;
/**
* A maximum size for this view.
*
* @remarks If none, set it to `Number.POSITIVE_INFINITY`.
*/
readonly maximumSize: number;
/**
* The priority of the view when the {@link SplitView.resize layout} algorithm
* runs. Views with higher priority will be resized first.
*
* @remarks Only used when `proportionalLayout` is false.
*/
readonly priority?: LayoutPriority;
/**
* If the {@link SplitView} supports {@link ISplitViewOptions.proportionalLayout proportional layout},
* this property allows for finer control over the proportional layout algorithm, per view.
*
* @defaultValue `true`
*/
readonly proportionalLayout?: boolean;
/**
* Whether the view will snap whenever the user reaches its minimum size or
* attempts to grow it beyond the minimum size.
*
* @defaultValue `false`
*/
readonly snap?: boolean;
/**
* View instances are supposed to fire the {@link IView.onDidChange} event whenever
* any of the constraint properties have changed:
*
* - {@link IView.minimumSize}
* - {@link IView.maximumSize}
* - {@link IView.priority}
* - {@link IView.snap}
*
* The SplitView will relayout whenever that happens. The event can optionally emit
* the view's preferred size for that relayout.
*/
readonly onDidChange: Event<number | undefined>;
/**
* This will be called by the {@link SplitView} during layout. A view meant to
* pass along the layout information down to its descendants.
*
* @param size The size of this view, in pixels.
* @param offset The offset of this view, relative to the start of the {@link SplitView}.
* @param context The optional {@link IView layout context} passed to {@link SplitView.layout}.
*/
layout(size: number, offset: number, context: TLayoutContext | undefined): void;
/**
* This will be called by the {@link SplitView} whenever this view is made
* visible or hidden.
*
* @param visible Whether the view becomes visible.
*/
setVisible?(visible: boolean): void;
}
/**
* A descriptor for a {@link SplitView} instance.
*/
export interface ISplitViewDescriptor<TLayoutContext = undefined> {
/**
* The layout size of the {@link SplitView}.
*/
readonly size: number;
/**
* Descriptors for each {@link IView view}.
*/
readonly views: {
/**
* Whether the {@link IView view} is visible.
*
* @defaultValue `true`
*/
readonly visible?: boolean;
/**
* The size of the {@link IView view}.
*
* @defaultValue `true`
*/
readonly size: number;
/**
* The size of the {@link IView view}.
*
* @defaultValue `true`
*/
readonly view: IView<TLayoutContext>;
}[];
}
export interface ISplitViewOptions<TLayoutContext = undefined> {
/**
* Which axis the views align on.
*
* @defaultValue `Orientation.VERTICAL`
*/
readonly orientation?: Orientation;
/**
* Styles overriding the {@link defaultStyles default ones}.
*/
readonly styles?: ISplitViewStyles;
/**
* Make Alt-drag the default drag operation.
*/
readonly inverseAltBehavior?: boolean;
/**
* Resize each view proportionally when resizing the SplitView.
*
* @defaultValue `true`
*/
readonly proportionalLayout?: boolean;
/**
* An initial description of this {@link SplitView} instance, allowing
* to initialze all views within the ctor.
*/
readonly descriptor?: ISplitViewDescriptor<TLayoutContext>;
/**
* The scrollbar visibility setting for whenever the views within
* the {@link SplitView} overflow.
*/
readonly scrollbarVisibility?: ScrollbarVisibility;
/**
* Override the orthogonal size of sashes.
*/
readonly getSashOrthogonalSize?: () => number;
}
interface ISashItem {
sash: Sash;
disposable: IDisposable;
}
/**
* When adding or removing views, uniformly distribute the entire split view space among
* all views.
*/
export type DistributeSizing = {
type: 'distribute';
};
/**
* When adding a view, make space for it by reducing the size of another view,
* indexed by the provided `index`.
*/
export type SplitSizing = {
type: 'split';
index: number;
};
/**
* When adding or removing views, assume the view is invisible.
*/
export type InvisibleSizing = {
type: 'invisible';
cachedVisibleSize: number;
};
/**
* When adding or removing views, the sizing provides fine grained
* control over how other views get resized.
*/
export type Sizing = DistributeSizing | SplitSizing | InvisibleSizing;
export declare namespace Sizing {
/**
* When adding or removing views, distribute the delta space among
* all other views.
*/
const Distribute: DistributeSizing;
/**
* When adding or removing views, split the delta space with another
* specific view, indexed by the provided `index`.
*/
function Split(index: number): SplitSizing;
/**
* When adding or removing views, assume the view is invisible.
*/
function Invisible(cachedVisibleSize: number): InvisibleSizing;
}
/**
* The {@link SplitView} is the UI component which implements a one dimensional
* flex-like layout algorithm for a collection of {@link IView} instances, which
* are essentially HTMLElement instances with the following size constraints:
*
* - {@link IView.minimumSize}
* - {@link IView.maximumSize}
* - {@link IView.priority}
* - {@link IView.snap}
*
* In case the SplitView doesn't have enough size to fit all views, it will overflow
* its content with a scrollbar.
*
* In between each pair of views there will be a {@link Sash} allowing the user
* to resize the views, making sure the constraints are respected.
*
* An optional {@link TLayoutContext layout context type} may be used in order to
* pass along layout contextual data from the {@link SplitView.layout} method down
* to each view's {@link IView.layout} calls.
*
* Features:
* - Flex-like layout algorithm
* - Snap support
* - Orthogonal sash support, for corner sashes
* - View hide/show support
* - View swap/move support
* - Alt key modifier behavior, macOS style
*/
export declare class SplitView<TLayoutContext = undefined> extends Disposable {
/**
* This {@link SplitView}'s orientation.
*/
readonly orientation: Orientation;
/**
* The DOM element representing this {@link SplitView}.
*/
readonly el: HTMLElement;
private sashContainer;
private viewContainer;
private scrollable;
private scrollableElement;
private size;
private layoutContext;
private contentSize;
private proportions;
private viewItems;
sashItems: ISashItem[];
private sashDragState;
private state;
private inverseAltBehavior;
private proportionalLayout;
private readonly getSashOrthogonalSize;
private _onDidSashChange;
private _onDidSashReset;
private _orthogonalStartSash;
private _orthogonalEndSash;
private _startSnappingEnabled;
private _endSnappingEnabled;
/**
* Fires whenever the user resizes a {@link Sash sash}.
*/
readonly onDidSashChange: Event<number>;
/**
* Fires whenever the user double clicks a {@link Sash sash}.
*/
readonly onDidSashReset: Event<number>;
/**
* Fires whenever the split view is scrolled.
*/
readonly onDidScroll: Event<ScrollEvent>;
/**
* The amount of views in this {@link SplitView}.
*/
get length(): number;
/**
* The minimum size of this {@link SplitView}.
*/
get minimumSize(): number;
/**
* The maximum size of this {@link SplitView}.
*/
get maximumSize(): number;
get orthogonalStartSash(): Sash | undefined;
get orthogonalEndSash(): Sash | undefined;
get startSnappingEnabled(): boolean;
get endSnappingEnabled(): boolean;
/**
* A reference to a sash, perpendicular to all sashes in this {@link SplitView},
* located at the left- or top-most side of the SplitView.
* Corner sashes will be created automatically at the intersections.
*/
set orthogonalStartSash(sash: Sash | undefined);
/**
* A reference to a sash, perpendicular to all sashes in this {@link SplitView},
* located at the right- or bottom-most side of the SplitView.
* Corner sashes will be created automatically at the intersections.
*/
set orthogonalEndSash(sash: Sash | undefined);
/**
* The internal sashes within this {@link SplitView}.
*/
get sashes(): readonly Sash[];
/**
* Enable/disable snapping at the beginning of this {@link SplitView}.
*/
set startSnappingEnabled(startSnappingEnabled: boolean);
/**
* Enable/disable snapping at the end of this {@link SplitView}.
*/
set endSnappingEnabled(endSnappingEnabled: boolean);
/**
* Create a new {@link SplitView} instance.
*/
constructor(container: HTMLElement, options?: ISplitViewOptions<TLayoutContext>);
style(styles: ISplitViewStyles): void;
/**
* Add a {@link IView view} to this {@link SplitView}.
*
* @param view The view to add.
* @param size Either a fixed size, or a dynamic {@link Sizing} strategy.
* @param index The index to insert the view on.
* @param skipLayout Whether layout should be skipped.
*/
addView(view: IView<TLayoutContext>, size: number | Sizing, index?: number, skipLayout?: boolean): void;
/**
* Remove a {@link IView view} from this {@link SplitView}.
*
* @param index The index where the {@link IView view} is located.
* @param sizing Whether to distribute other {@link IView view}'s sizes.
*/
removeView(index: number, sizing?: Sizing): IView<TLayoutContext>;
/**
* Move a {@link IView view} to a different index.
*
* @param from The source index.
* @param to The target index.
*/
moveView(from: number, to: number): void;
/**
* Swap two {@link IView views}.
*
* @param from The source index.
* @param to The target index.
*/
swapViews(from: number, to: number): void;
/**
* Returns whether the {@link IView view} is visible.
*
* @param index The {@link IView view} index.
*/
isViewVisible(index: number): boolean;
/**
* Set a {@link IView view}'s visibility.
*
* @param index The {@link IView view} index.
* @param visible Whether the {@link IView view} should be visible.
*/
setViewVisible(index: number, visible: boolean): void;
/**
* Returns the {@link IView view}'s size previously to being hidden.
*
* @param index The {@link IView view} index.
*/
getViewCachedVisibleSize(index: number): number | undefined;
/**
* Layout the {@link SplitView}.
*
* @param size The entire size of the {@link SplitView}.
* @param layoutContext An optional layout context to pass along to {@link IView views}.
*/
layout(size: number, layoutContext?: TLayoutContext): void;
private saveProportions;
private onSashStart;
private onSashChange;
private onSashEnd;
private onViewChange;
/**
* Resize a {@link IView view} within the {@link SplitView}.
*
* @param index The {@link IView view} index.
* @param size The {@link IView view} size.
*/
resizeView(index: number, size: number): void;
/**
* Returns whether all other {@link IView views} are at their minimum size.
*/
isViewSizeMaximized(index: number): boolean;
/**
* Distribute the entire {@link SplitView} size among all {@link IView views}.
*/
distributeViewSizes(): void;
/**
* Returns the size of a {@link IView view}.
*/
getViewSize(index: number): number;
private doAddView;
private relayout;
private resize;
private distributeEmptySpace;
private layoutViews;
private updateScrollableElement;
private updateSashEnablement;
private getSashPosition;
private findFirstSnapIndex;
dispose(): void;
}