Add scrollbar.showScrollbar

Fixes #5676
This commit is contained in:
Daniel Imms
2026-02-05 07:20:23 -08:00
parent 6f163beb97
commit c2db7d4c8a
14 changed files with 115 additions and 32 deletions
+2 -1
View File
@@ -82,10 +82,11 @@ export abstract class AbstractScrollbar extends Widget {
/**
* Creates the dom node for an arrow & adds it to the container
*/
protected _createArrow(opts: IScrollbarArrowOptions): void {
protected _createArrow(opts: IScrollbarArrowOptions): ScrollbarArrow {
const arrow = this._register(new ScrollbarArrow(opts));
this.domNode.domNode.appendChild(arrow.bgDomNode);
this.domNode.domNode.appendChild(arrow.domNode);
return arrow;
}
/**
@@ -314,6 +314,12 @@ export class SmoothScrollableElement extends Widget {
if (typeof newOptions.vertical !== 'undefined') {
this._options.vertical = newOptions.vertical;
}
if (typeof newOptions.horizontalHasArrows !== 'undefined') {
this._options.horizontalHasArrows = newOptions.horizontalHasArrows;
}
if (typeof newOptions.verticalHasArrows !== 'undefined') {
this._options.verticalHasArrows = newOptions.verticalHasArrows;
}
if (typeof newOptions.horizontalScrollbarSize !== 'undefined') {
this._options.horizontalScrollbarSize = newOptions.horizontalScrollbarSize;
}
@@ -128,8 +128,10 @@ export interface IScrollableElementChangeOptions {
scrollPredominantAxis?: boolean;
horizontal?: ScrollbarVisibility;
horizontalScrollbarSize?: number;
horizontalHasArrows?: boolean;
vertical?: ScrollbarVisibility;
verticalScrollbarSize?: number;
verticalHasArrows?: boolean;
scrollByPage?: boolean;
}
+9 -1
View File
@@ -35,7 +35,7 @@ export class ScrollbarState {
* For the vertical scrollbar: the height of the scrollbar's arrows.
* For the horizontal scrollbar: the width of the scrollbar's arrows.
*/
private readonly _arrowSize: number;
private _arrowSize: number;
// --- variables
/**
@@ -127,6 +127,14 @@ export class ScrollbarState {
this._scrollbarSize = Math.round(scrollbarSize);
}
public setArrowSize(arrowSize: number): void {
const iArrowSize = Math.round(arrowSize);
if (this._arrowSize !== iArrowSize) {
this._arrowSize = iArrowSize;
this._refreshComputedValues();
}
}
public setOppositeScrollbarSize(oppositeScrollbarSize: number): void {
this._oppositeScrollbarSize = Math.round(oppositeScrollbarSize);
}
+56 -21
View File
@@ -7,17 +7,22 @@ import { AbstractScrollbar, ISimplifiedPointerEvent, IScrollbarHost } from './ab
import { IScrollableElementResolvedOptions } from './scrollableElementOptions';
import { ScrollbarState } from './scrollbarState';
import { INewScrollPosition, Scrollable, ScrollbarVisibility, IScrollEvent } from './scrollable';
import type { ScrollbarArrow } from './scrollbarArrow';
export class VerticalScrollbar extends AbstractScrollbar {
private _arrowUp: ScrollbarArrow | undefined;
private _arrowDown: ScrollbarArrow | undefined;
private _arrowScrollDelta: number = 0;
constructor(scrollable: Scrollable, options: IScrollableElementResolvedOptions, host: IScrollbarHost) {
const scrollDimensions = scrollable.getScrollDimensions();
const scrollPosition = scrollable.getCurrentScrollPosition();
const hasArrows = options.verticalHasArrows;
super({
lazyRender: options.lazyRender,
host: host,
scrollbarState: new ScrollbarState(
(options.verticalHasArrows ? options.verticalScrollbarSize : 0),
(hasArrows ? options.verticalScrollbarSize : 0),
(options.vertical === ScrollbarVisibility.HIDDEN ? 0 : options.verticalScrollbarSize),
0,
scrollDimensions.height,
@@ -30,26 +35,7 @@ export class VerticalScrollbar extends AbstractScrollbar {
scrollByPage: options.scrollByPage
});
if (options.verticalHasArrows) {
const arrowSize = options.verticalScrollbarSize;
const arrowDelta = 0;
this._createArrow({
className: 'xterm-scra xterm-arrow-up',
top: arrowDelta,
left: arrowDelta,
bgWidth: options.verticalScrollbarSize,
bgHeight: arrowSize,
handleActivate: () => this._arrowScroll(-arrowSize)
});
this._createArrow({
className: 'xterm-scra xterm-arrow-down',
bottom: arrowDelta,
left: arrowDelta,
bgWidth: options.verticalScrollbarSize,
bgHeight: arrowSize,
handleActivate: () => this._arrowScroll(arrowSize)
});
}
this._setArrows(hasArrows, options.verticalScrollbarSize);
this._createSlider(0, Math.floor((options.verticalScrollbarSize - options.verticalSliderSize) / 2), options.verticalSliderSize, undefined);
}
@@ -98,7 +84,56 @@ export class VerticalScrollbar extends AbstractScrollbar {
this._scrollable.setScrollPositionNow({ scrollTop: currentPosition.scrollTop + delta });
}
private _setArrows(showArrows: boolean, size: number): void {
this._arrowScrollDelta = size;
if (!this._arrowUp || !this._arrowDown) {
const arrowDelta = 0;
this._arrowUp = this._createArrow({
className: 'xterm-scra xterm-arrow-up',
top: arrowDelta,
left: arrowDelta,
bgWidth: size,
bgHeight: size,
handleActivate: () => this._arrowScroll(-this._arrowScrollDelta)
});
this._arrowDown = this._createArrow({
className: 'xterm-scra xterm-arrow-down',
bottom: arrowDelta,
left: arrowDelta,
bgWidth: size,
bgHeight: size,
handleActivate: () => this._arrowScroll(this._arrowScrollDelta)
});
}
this._updateArrowSize(this._arrowUp, size);
this._updateArrowSize(this._arrowDown, size);
if (!this._arrowUp || !this._arrowDown) {
return;
}
const display = showArrows ? '' : 'none';
this._arrowUp.bgDomNode.style.display = display;
this._arrowUp.domNode.style.display = display;
this._arrowDown.bgDomNode.style.display = display;
this._arrowDown.domNode.style.display = display;
}
private _updateArrowSize(arrow: ScrollbarArrow | undefined, size: number): void {
if (!arrow) {
return;
}
arrow.bgDomNode.style.width = `${size}px`;
arrow.bgDomNode.style.height = `${size}px`;
arrow.domNode.style.width = `${size}px`;
arrow.domNode.style.height = `${size}px`;
}
public updateOptions(options: IScrollableElementResolvedOptions): void {
const arrowSize = options.verticalHasArrows ? options.verticalScrollbarSize : 0;
this._scrollbarState.setArrowSize(arrowSize);
this._setArrows(options.verticalHasArrows, options.verticalScrollbarSize);
this.updateScrollbarSize(options.vertical === ScrollbarVisibility.HIDDEN ? 0 : options.verticalScrollbarSize);
this._scrollbarState.setOppositeScrollbarSize(0);
this._visibilityController.setVisibility(options.vertical);