提交 8120b8f4 编写于 作者: A Alex Dima

Extract ScrollbarState to its own file

上级 83ee1c98
......@@ -14,6 +14,7 @@ import {GlobalMouseMoveMonitor, IStandardMouseMoveEventData, standardMouseMoveMe
import {Widget} from 'vs/base/browser/ui/widget';
import {TimeoutTimer, IntervalTimer} from 'vs/base/common/async';
import {FastDomNode, createFastDomNode} from 'vs/base/browser/styleMutator';
import {ScrollbarState} from 'vs/base/browser/ui/scrollbar/scrollbarState';
/**
* The arrow image size.
......@@ -25,189 +26,13 @@ export const ARROW_IMG_SIZE = 11;
*/
const MOUSE_DRAG_RESET_DISTANCE = 140;
/**
* The minimal size of the slider (such that it can still be clickable) -- it is artificially enlarged.
*/
const MINIMUM_SLIDER_SIZE = 20;
export interface IMouseWheelEventFactory {
(): IMouseWheelEvent;
}
export class ScrollbarState {
// --- immutable
private _scrollbarSize: number;
private _oppositeScrollbarSize: number;
private _arrowSize: number;
// --- variables
private _visibleSize: number;
private _scrollSize: number;
private _scrollPosition: number;
// --- computed variables
/**
* `visibleSize` - `oppositeScrollbarSize`
*/
private _computedAvailableSize: number;
/**
* `computedAvailableSize` - 2 * `arrowSize`
*/
private _computedRepresentableSize: number;
/**
* `computedRepresentableSize` / `scrollSize`
*/
private _computedRatio: number;
/**
* (`scrollSize` > `visibleSize`)
*/
private _computedIsNeeded: boolean;
private _computedSliderSize: number;
private _computedSliderPosition: number;
constructor(arrowSize: number, scrollbarSize: number, oppositeScrollbarSize: number) {
this._scrollbarSize = Math.round(scrollbarSize);
this._oppositeScrollbarSize = Math.round(oppositeScrollbarSize);
this._arrowSize = Math.round(arrowSize);
this._visibleSize = 0;
this._scrollSize = 0;
this._scrollPosition = 0;
this._computedAvailableSize = 0;
this._computedRepresentableSize = 0;
this._computedRatio = 0.1;
this._computedIsNeeded = false;
this._computedSliderSize = 0;
this._computedSliderPosition = 0;
this._refreshComputedValues();
}
public setVisibleSize(visibleSize: number): boolean {
let iVisibleSize = Math.round(visibleSize);
if (this._visibleSize !== iVisibleSize) {
this._visibleSize = iVisibleSize;
this._refreshComputedValues();
return true;
}
return false;
}
public setScrollSize(scrollSize: number): boolean {
let iScrollSize = Math.round(scrollSize);
if (this._scrollSize !== iScrollSize) {
this._scrollSize = iScrollSize;
this._refreshComputedValues();
return true;
}
return false;
}
public setScrollPosition(scrollPosition: number): boolean {
let iScrollPosition = Math.round(scrollPosition);
if (this._scrollPosition !== iScrollPosition) {
this._scrollPosition = iScrollPosition;
this._refreshComputedValues();
return true;
}
return false;
}
private _refreshComputedValues(): void {
const oppositeScrollbarSize = this._oppositeScrollbarSize;
const arrowSize = this._arrowSize;
const visibleSize = this._visibleSize;
const scrollSize = this._scrollSize;
const scrollPosition = this._scrollPosition;
let computedAvailableSize = Math.max(0, visibleSize - oppositeScrollbarSize);
let computedRepresentableSize = Math.max(0, computedAvailableSize - 2 * arrowSize);
let computedRatio = scrollSize > 0 ? (computedRepresentableSize / scrollSize) : 0;
let computedIsNeeded = (scrollSize > visibleSize);
let computedSliderSize: number;
let computedSliderPosition: number;
if (!computedIsNeeded) {
computedSliderSize = computedRepresentableSize;
computedSliderPosition = 0;
} else {
computedSliderSize = Math.floor(visibleSize * computedRatio);
computedSliderPosition = Math.floor(scrollPosition * computedRatio);
if (computedSliderSize < MINIMUM_SLIDER_SIZE) {
// We must artificially increase the size of the slider, since the slider would be too small otherwise
// The effort is to keep the slider centered around the original position, but we must take into
// account the cases when the slider is too close to the top or too close to the bottom
let sliderArtificialOffset = (MINIMUM_SLIDER_SIZE - computedSliderSize) / 2;
computedSliderSize = MINIMUM_SLIDER_SIZE;
computedSliderPosition -= sliderArtificialOffset;
if (computedSliderPosition + computedSliderSize > computedRepresentableSize) {
// Slider is too close to the bottom, so we glue it to the bottom
computedSliderPosition = computedRepresentableSize - computedSliderSize;
}
if (computedSliderPosition < 0) {
// Slider is too close to the top, so we glue it to the top
computedSliderPosition = 0;
}
}
}
this._computedAvailableSize = Math.round(computedAvailableSize);
this._computedRepresentableSize = Math.round(computedRepresentableSize);
this._computedRatio = computedRatio;
this._computedIsNeeded = computedIsNeeded;
this._computedSliderSize = Math.round(computedSliderSize);
this._computedSliderPosition = Math.round(computedSliderPosition);
}
public getArrowSize(): number {
return this._arrowSize;
}
public getRectangleLargeSize(): number {
return this._computedAvailableSize;
}
public getRectangleSmallSize(): number {
return this._scrollbarSize;
}
public isNeeded(): boolean {
return this._computedIsNeeded;
}
public getSliderSize(): number {
return this._computedSliderSize;
}
public getSliderPosition(): number {
return this._computedSliderPosition;
}
public convertSliderPositionToScrollPosition(desiredSliderPosition: number): number {
return desiredSliderPosition / this._computedRatio;
}
public validateScrollPosition(desiredScrollPosition: number): number {
desiredScrollPosition = Math.round(desiredScrollPosition);
desiredScrollPosition = Math.max(desiredScrollPosition, 0);
desiredScrollPosition = Math.min(desiredScrollPosition, this._scrollSize - this._visibleSize);
return desiredScrollPosition;
}
}
class ScrollbarArrow extends Widget {
private _parent: IParent;
......
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
/**
* The minimal size of the slider (such that it can still be clickable) -- it is artificially enlarged.
*/
const MINIMUM_SLIDER_SIZE = 20;
export class ScrollbarState {
// --- immutable
private _scrollbarSize: number;
private _oppositeScrollbarSize: number;
private _arrowSize: number;
// --- variables
private _visibleSize: number;
private _scrollSize: number;
private _scrollPosition: number;
// --- computed variables
/**
* `visibleSize` - `oppositeScrollbarSize`
*/
private _computedAvailableSize: number;
/**
* `computedAvailableSize` - 2 * `arrowSize`
*/
private _computedRepresentableSize: number;
/**
* `computedRepresentableSize` / `scrollSize`
*/
private _computedRatio: number;
/**
* (`scrollSize` > `visibleSize`)
*/
private _computedIsNeeded: boolean;
private _computedSliderSize: number;
private _computedSliderPosition: number;
constructor(arrowSize: number, scrollbarSize: number, oppositeScrollbarSize: number) {
this._scrollbarSize = Math.round(scrollbarSize);
this._oppositeScrollbarSize = Math.round(oppositeScrollbarSize);
this._arrowSize = Math.round(arrowSize);
this._visibleSize = 0;
this._scrollSize = 0;
this._scrollPosition = 0;
this._computedAvailableSize = 0;
this._computedRepresentableSize = 0;
this._computedRatio = 0.1;
this._computedIsNeeded = false;
this._computedSliderSize = 0;
this._computedSliderPosition = 0;
this._refreshComputedValues();
}
public setVisibleSize(visibleSize: number): boolean {
let iVisibleSize = Math.round(visibleSize);
if (this._visibleSize !== iVisibleSize) {
this._visibleSize = iVisibleSize;
this._refreshComputedValues();
return true;
}
return false;
}
public setScrollSize(scrollSize: number): boolean {
let iScrollSize = Math.round(scrollSize);
if (this._scrollSize !== iScrollSize) {
this._scrollSize = iScrollSize;
this._refreshComputedValues();
return true;
}
return false;
}
public setScrollPosition(scrollPosition: number): boolean {
let iScrollPosition = Math.round(scrollPosition);
if (this._scrollPosition !== iScrollPosition) {
this._scrollPosition = iScrollPosition;
this._refreshComputedValues();
return true;
}
return false;
}
private _refreshComputedValues(): void {
const oppositeScrollbarSize = this._oppositeScrollbarSize;
const arrowSize = this._arrowSize;
const visibleSize = this._visibleSize;
const scrollSize = this._scrollSize;
const scrollPosition = this._scrollPosition;
let computedAvailableSize = Math.max(0, visibleSize - oppositeScrollbarSize);
let computedRepresentableSize = Math.max(0, computedAvailableSize - 2 * arrowSize);
let computedRatio = scrollSize > 0 ? (computedRepresentableSize / scrollSize) : 0;
let computedIsNeeded = (scrollSize > visibleSize);
let computedSliderSize: number;
let computedSliderPosition: number;
if (!computedIsNeeded) {
computedSliderSize = computedRepresentableSize;
computedSliderPosition = 0;
} else {
computedSliderSize = Math.floor(visibleSize * computedRatio);
computedSliderPosition = Math.floor(scrollPosition * computedRatio);
if (computedSliderSize < MINIMUM_SLIDER_SIZE) {
// We must artificially increase the size of the slider, since the slider would be too small otherwise
// The effort is to keep the slider centered around the original position, but we must take into
// account the cases when the slider is too close to the top or too close to the bottom
let sliderArtificialOffset = (MINIMUM_SLIDER_SIZE - computedSliderSize) / 2;
computedSliderSize = MINIMUM_SLIDER_SIZE;
computedSliderPosition -= sliderArtificialOffset;
if (computedSliderPosition + computedSliderSize > computedRepresentableSize) {
// Slider is too close to the bottom, so we glue it to the bottom
computedSliderPosition = computedRepresentableSize - computedSliderSize;
}
if (computedSliderPosition < 0) {
// Slider is too close to the top, so we glue it to the top
computedSliderPosition = 0;
}
}
}
this._computedAvailableSize = Math.round(computedAvailableSize);
this._computedRepresentableSize = Math.round(computedRepresentableSize);
this._computedRatio = computedRatio;
this._computedIsNeeded = computedIsNeeded;
this._computedSliderSize = Math.round(computedSliderSize);
this._computedSliderPosition = Math.round(computedSliderPosition);
}
public getArrowSize(): number {
return this._arrowSize;
}
public getRectangleLargeSize(): number {
return this._computedAvailableSize;
}
public getRectangleSmallSize(): number {
return this._scrollbarSize;
}
public isNeeded(): boolean {
return this._computedIsNeeded;
}
public getSliderSize(): number {
return this._computedSliderSize;
}
public getSliderPosition(): number {
return this._computedSliderPosition;
}
public convertSliderPositionToScrollPosition(desiredSliderPosition: number): number {
return desiredSliderPosition / this._computedRatio;
}
public validateScrollPosition(desiredScrollPosition: number): number {
desiredScrollPosition = Math.round(desiredScrollPosition);
desiredScrollPosition = Math.max(desiredScrollPosition, 0);
desiredScrollPosition = Math.min(desiredScrollPosition, this._scrollSize - this._visibleSize);
return desiredScrollPosition;
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册