Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add setting to control the sash size #97266

Merged
merged 4 commits into from May 12, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions build/lib/i18n.resources.json
Expand Up @@ -138,6 +138,10 @@
"name": "vs/workbench/contrib/relauncher",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/contrib/sash",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/contrib/scm",
"project": "vscode-workbench"
Expand Down
57 changes: 1 addition & 56 deletions src/vs/base/browser/ui/sash/sash.css
Expand Up @@ -13,13 +13,6 @@
pointer-events: none;
}

.monaco-sash.vertical {
cursor: ew-resize;
top: 0;
width: 4px;
height: 100%;
}

.monaco-sash.mac.vertical {
cursor: col-resize;
}
Expand All @@ -32,13 +25,6 @@
cursor: w-resize;
}

.monaco-sash.horizontal {
cursor: ns-resize;
left: 0;
width: 100%;
height: 4px;
}

.monaco-sash.mac.horizontal {
cursor: row-resize;
}
Expand All @@ -51,52 +37,11 @@
cursor: n-resize;
}

.monaco-sash:not(.disabled).orthogonal-start::before,
.monaco-sash:not(.disabled).orthogonal-end::after {
content: ' ';
height: 8px;
width: 8px;
z-index: 100;
display: block;
cursor: all-scroll;
position: absolute;
}

.monaco-sash.orthogonal-start.vertical::before {
left: -2px;
top: -4px;
}

.monaco-sash.orthogonal-end.vertical::after {
left: -2px;
bottom: -4px;
}

.monaco-sash.orthogonal-start.horizontal::before {
top: -2px;
left: -4px;
}

.monaco-sash.orthogonal-end.horizontal::after {
top: -2px;
right: -4px;
}

.monaco-sash.disabled {
cursor: default !important;
pointer-events: none !important;
}

/** Touch **/

.monaco-sash.touch.vertical {
width: 20px;
}

.monaco-sash.touch.horizontal {
height: 20px;
}

/** Debug **/

.monaco-sash.debug {
Expand All @@ -110,4 +55,4 @@
.monaco-sash.debug:not(.disabled).orthogonal-start::before,
.monaco-sash.debug:not(.disabled).orthogonal-end::after {
background: red;
}
}
41 changes: 22 additions & 19 deletions src/vs/base/browser/ui/sash/sash.ts
Expand Up @@ -5,7 +5,6 @@

import 'vs/css!./sash';
import { IDisposable, dispose, Disposable, DisposableStore } from 'vs/base/common/lifecycle';
import { isIPad } from 'vs/base/browser/browser';
import { isMacintosh } from 'vs/base/common/platform';
import * as types from 'vs/base/common/types';
import { EventType, GestureEvent, Gesture } from 'vs/base/browser/touch';
Expand All @@ -15,6 +14,7 @@ import { getElementsByTagName, EventHelper, createStyleSheet, addDisposableListe
import { domEvent } from 'vs/base/browser/event';

const DEBUG = false;
let globalSashSize = 4;

export interface ISashLayoutProvider { }

Expand Down Expand Up @@ -56,12 +56,19 @@ export const enum SashState {
Enabled
}

export class Sash extends Disposable {
const _onDidChangeGlobalSize = new Emitter<number>();
const onDidChangeGlobalSize: Event<number> = _onDidChangeGlobalSize.event;
export function setGlobalSashSize(size: number): void {
globalSashSize = size;
_onDidChangeGlobalSize.fire(size);
}

export class Sash extends Disposable {
private el: HTMLElement;
private layoutProvider: ISashLayoutProvider;
private hidden: boolean;
private orientation!: Orientation;
private size: number = globalSashSize;

private _state: SashState = SashState.Enabled;
get state(): SashState { return this._state; }
Expand Down Expand Up @@ -142,19 +149,19 @@ export class Sash extends Disposable {
this._register(Gesture.addTarget(this.el));
this._register(domEvent(this.el, EventType.Start)(this.onTouchStart, this));

if (isIPad) {
// see also https://ux.stackexchange.com/questions/39023/what-is-the-optimum-button-size-of-touch-screen-applications
addClass(this.el, 'touch');
}

this.setOrientation(options.orientation || Orientation.VERTICAL);
this._register(onDidChangeGlobalSize(size => {
this.size = size;
this.layout();
}));

this.hidden = false;
this.layoutProvider = layoutProvider;

this.orthogonalStartSash = options.orthogonalStartSash;
this.orthogonalEndSash = options.orthogonalEndSash;

this.setOrientation(options.orientation || Orientation.VERTICAL);

toggleClass(this.el, 'debug', DEBUG);
}

Expand All @@ -169,9 +176,7 @@ export class Sash extends Disposable {
addClass(this.el, 'vertical');
}

if (this.layoutProvider) {
this.layout();
}
this.layout();
}

private onMouseDown(e: MouseEvent): void {
Expand Down Expand Up @@ -331,11 +336,9 @@ export class Sash extends Disposable {
}

layout(): void {
const size = isIPad ? 20 : 4;

if (this.orientation === Orientation.VERTICAL) {
const verticalProvider = (<IVerticalSashLayoutProvider>this.layoutProvider);
this.el.style.left = verticalProvider.getVerticalSashLeft(this) - (size / 2) + 'px';
this.el.style.left = verticalProvider.getVerticalSashLeft(this) - (this.size / 2) + 'px';

if (verticalProvider.getVerticalSashTop) {
this.el.style.top = verticalProvider.getVerticalSashTop(this) + 'px';
Expand All @@ -346,7 +349,7 @@ export class Sash extends Disposable {
}
} else {
const horizontalProvider = (<IHorizontalSashLayoutProvider>this.layoutProvider);
this.el.style.top = horizontalProvider.getHorizontalSashTop(this) - (size / 2) + 'px';
this.el.style.top = horizontalProvider.getHorizontalSashTop(this) - (this.size / 2) + 'px';

if (horizontalProvider.getHorizontalSashLeft) {
this.el.style.left = horizontalProvider.getHorizontalSashLeft(this) + 'px';
Expand Down Expand Up @@ -384,15 +387,15 @@ export class Sash extends Disposable {

private getOrthogonalSash(e: MouseEvent): Sash | undefined {
if (this.orientation === Orientation.VERTICAL) {
if (e.offsetY <= 4) {
if (e.offsetY <= this.size) {
return this.orthogonalStartSash;
} else if (e.offsetY >= this.el.clientHeight - 4) {
} else if (e.offsetY >= this.el.clientHeight - this.size) {
return this.orthogonalEndSash;
}
} else {
if (e.offsetX <= 4) {
if (e.offsetX <= this.size) {
return this.orthogonalStartSash;
} else if (e.offsetX >= this.el.clientWidth - 4) {
} else if (e.offsetX >= this.el.clientWidth - this.size) {
return this.orthogonalEndSash;
}
}
Expand Down
31 changes: 31 additions & 0 deletions src/vs/workbench/contrib/sash/browser/sash.contribution.ts
@@ -0,0 +1,31 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { localize } from 'vs/nls';
import { IConfigurationRegistry, Extensions as ConfigurationExtensions } from 'vs/platform/configuration/common/configurationRegistry';
import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
import { Registry } from 'vs/platform/registry/common/platform';
import { workbenchConfigurationNodeBase } from 'vs/workbench/common/configuration';
import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions';
import { SashSizeController, minSize, maxSize } from 'vs/workbench/contrib/sash/browser/sash';

// Sash size contribution
Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench)
.registerWorkbenchContribution(SashSizeController, LifecyclePhase.Restored);

// Sash size configuration contribution
Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration)
.registerConfiguration({
...workbenchConfigurationNodeBase,
'properties': {
'workbench.sash.size': {
'type': 'number',
'default': minSize,
'minimum': minSize,
'maximum': maxSize,
'description': localize('sashSize', "Controls the size of the sash.")
},
}
});
52 changes: 52 additions & 0 deletions src/vs/workbench/contrib/sash/browser/sash.ts
@@ -0,0 +1,52 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { isIPad } from 'vs/base/browser/browser';
import { createStyleSheet } from 'vs/base/browser/dom';
import { setGlobalSashSize } from 'vs/base/browser/ui/sash/sash';
import { Event } from 'vs/base/common/event';
import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';

export const minSize = 4;
export const maxSize = 20; // see also https://ux.stackexchange.com/questions/39023/what-is-the-optimum-button-size-of-touch-screen-applications

export class SashSizeController extends Disposable implements IWorkbenchContribution {
private readonly configurationName = 'workbench.sash.size';
private stylesheet: HTMLStyleElement;

constructor(
@IConfigurationService private readonly configurationService: IConfigurationService
) {
super();

this.stylesheet = createStyleSheet();
this._register(toDisposable(() => this.stylesheet.remove()));

const onDidChangeSizeConfiguration = Event.filter(configurationService.onDidChangeConfiguration, e => e.affectsConfiguration(this.configurationName));
this._register(onDidChangeSizeConfiguration(this.onDidChangeSizeConfiguration, this));
this.onDidChangeSizeConfiguration();
}

private onDidChangeSizeConfiguration(): void {
const size = isIPad ? maxSize : this.configurationService.getValue<number>(this.configurationName);

if (size && size >= minSize && size <= maxSize) {
// Update styles
this.stylesheet.innerHTML = `
.monaco-sash.vertical { cursor: ew-resize; top: 0; width: ${size}px; height: 100%; }
.monaco-sash.horizontal { cursor: ns-resize; left: 0; width: 100%; height: ${size}px; }
.monaco-sash:not(.disabled).orthogonal-start::before, .monaco-sash:not(.disabled).orthogonal-end::after { content: ' '; height: ${size * 2}px; width: ${size * 2}px; z-index: 100; display: block; cursor: all-scroll; position: absolute; }
.monaco-sash.orthogonal-start.vertical::before { left: -${size / 2}px; top: -${size}px; }
.monaco-sash.orthogonal-end.vertical::after { left: -${size / 2}px; bottom: -${size}px; }
.monaco-sash.orthogonal-start.horizontal::before { top: -${size / 2}px; left: -${size}px; }
.monaco-sash.orthogonal-end.horizontal::after { top: -${size / 2}px; right: -${size}px; }`;

// Update behavor
setGlobalSashSize(size);
}
}
}
3 changes: 3 additions & 0 deletions src/vs/workbench/workbench.common.main.ts
Expand Up @@ -166,6 +166,9 @@ import 'vs/workbench/contrib/search/browser/searchView';
// Search Editor
import 'vs/workbench/contrib/searchEditor/browser/searchEditor.contribution';

// Sash
import 'vs/workbench/contrib/sash/browser/sash.contribution';

// SCM
import 'vs/workbench/contrib/scm/browser/scm.contribution';
import 'vs/workbench/contrib/scm/browser/scmViewlet';
Expand Down