提交 f1f5385a 编写于 作者: J Joao Moreno

💄 SourceControlInputBox.visible API

上级 4925df27
......@@ -570,6 +570,7 @@ export class Repository implements Disposable {
const root = Uri.file(repository.root);
this._sourceControl = scm.createSourceControl('git', 'Git', root);
this._sourceControl.inputBox.placeholder = localize('commitMessage', "Message (press {0} to commit)");
this._sourceControl.inputBox.visible = false;
this._sourceControl.acceptInputCommand = { command: 'git.commitWithInput', title: localize('commit', "Commit"), arguments: [this._sourceControl] };
this._sourceControl.quickDiffProvider = this;
this._sourceControl.inputBox.validateInput = this.validateInput.bind(this);
......
......@@ -720,11 +720,21 @@ declare module 'vscode' {
* An event signaling when the selection state changes.
*/
readonly onDidChangeSelection: Event<boolean>;
}
//#endregion
//#region Joao: SCM Input Box
/**
* Represents the input box in the Source Control viewlet.
*/
export interface SourceControlInputBox {
/**
* Whether the input box is hidden.
* Whether the input box is visible.
*/
hideInputBox: boolean;
visible: boolean;
}
//#endregion
......
......@@ -119,7 +119,6 @@ class MainThreadSCMProvider implements ISCMProvider {
get acceptInputCommand(): Command | undefined { return this.features.acceptInputCommand; }
get statusBarCommands(): Command[] | undefined { return this.features.statusBarCommands; }
get count(): number | undefined { return this.features.count; }
get hideInputBox(): boolean | undefined { return this.features.hideInputBox; }
private _onDidChangeCommitTemplate = new Emitter<string>();
get onDidChangeCommitTemplate(): Event<string> { return this._onDidChangeCommitTemplate.event; }
......@@ -396,6 +395,16 @@ export class MainThreadSCM implements MainThreadSCMShape {
repository.input.placeholder = placeholder;
}
$setInputBoxVisibility(sourceControlHandle: number, visible: boolean): void {
const repository = this._repositories[sourceControlHandle];
if (!repository) {
return;
}
repository.input.visible = visible;
}
$setValidationProviderIsEnabled(sourceControlHandle: number, enabled: boolean): void {
const repository = this._repositories[sourceControlHandle];
......
......@@ -535,7 +535,6 @@ export interface SCMProviderFeatures {
commitTemplate?: string;
acceptInputCommand?: modes.Command;
statusBarCommands?: modes.Command[];
hideInputBox?: boolean;
}
export interface SCMGroupFeatures {
......@@ -580,6 +579,7 @@ export interface MainThreadSCMShape extends IDisposable {
$setInputBoxValue(sourceControlHandle: number, value: string): void;
$setInputBoxPlaceholder(sourceControlHandle: number, placeholder: string): void;
$setInputBoxVisibility(sourceControlHandle: number, visible: boolean): void;
$setValidationProviderIsEnabled(sourceControlHandle: number, enabled: boolean): void;
}
......
......@@ -198,6 +198,18 @@ export class ExtHostSCMInputBox implements vscode.SourceControlInputBox {
this._proxy.$setValidationProviderIsEnabled(this._sourceControlHandle, !!fn);
}
private _visible: boolean = true;
get visible(): boolean {
return this._visible;
}
set visible(visible: boolean | undefined) {
visible = !!visible;
this._visible = visible;
this._proxy.$setInputBoxVisibility(this._sourceControlHandle, visible);
}
constructor(private _extension: IExtensionDescription, private _proxy: MainThreadSCMShape, private _sourceControlHandle: number) {
// noop
}
......@@ -439,17 +451,6 @@ class ExtHostSourceControl implements vscode.SourceControl {
return this._selected;
}
private _hideInputBox: boolean = false;
get hideInputBox(): boolean {
return this._hideInputBox;
}
set hideInputBox(hideInputBox: boolean | undefined) {
this._hideInputBox = hideInputBox;
this._proxy.$updateSourceControl(this.handle, { hideInputBox: !!hideInputBox });
}
private _onDidChangeSelection = new Emitter<boolean>();
readonly onDidChangeSelection = this._onDidChangeSelection.event;
......
......@@ -137,12 +137,12 @@
}
.scm-viewlet .scm-editor {
box-sizing: border-box;
padding: 5px 9px 5px 16px;
}
.scm-viewlet .scm-editor {
box-sizing: border-box;
padding: 5px 9px 5px 16px;
.scm-viewlet .scm-editor.hidden {
display: none;
}
.scm-viewlet .scm-editor > .monaco-inputbox {
......
......@@ -11,7 +11,7 @@ import { domEvent, stop } from 'vs/base/browser/event';
import { basename } from 'vs/base/common/paths';
import { IDisposable, dispose, combinedDisposable, Disposable, toDisposable } from 'vs/base/common/lifecycle';
import { PanelViewlet, ViewletPanel, IViewletPanelOptions } from 'vs/workbench/browser/parts/views/panelViewlet';
import { append, $, addClass, toggleClass, trackFocus, Dimension, addDisposableListener } from 'vs/base/browser/dom';
import { append, $, addClass, toggleClass, trackFocus, Dimension, addDisposableListener, removeClass } from 'vs/base/browser/dom';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { List } from 'vs/base/browser/ui/list/listWidget';
import { IListVirtualDelegate, IListRenderer, IListContextMenuEvent, IListEvent } from 'vs/base/browser/ui/list/list';
......@@ -814,59 +814,61 @@ export class RepositoryPanel extends ViewletPanel {
this.disposables.push(focusTracker);
// Input
if (!this.repository.provider.hideInputBox) {
this.inputBoxContainer = append(container, $('.scm-editor'));
const updatePlaceholder = () => {
const binding = this.keybindingService.lookupKeybinding('scm.acceptInput');
const label = binding ? binding.getLabel() : (platform.isMacintosh ? 'Cmd+Enter' : 'Ctrl+Enter');
const placeholder = format(this.repository.input.placeholder, label);
this.inputBox.setPlaceHolder(placeholder);
};
const validationDelayer = new ThrottledDelayer<any>(200);
const validate = () => {
return this.repository.input.validateInput(this.inputBox.value, this.inputBox.inputElement.selectionStart).then(result => {
if (!result) {
this.inputBox.inputElement.removeAttribute('aria-invalid');
this.inputBox.hideMessage();
} else {
this.inputBox.inputElement.setAttribute('aria-invalid', 'true');
this.inputBox.showMessage({ content: result.message, type: convertValidationType(result.type) });
}
});
};
const triggerValidation = () => validationDelayer.trigger(validate);
this.inputBox = new InputBox(this.inputBoxContainer, this.contextViewService, { flexibleHeight: true });
this.disposables.push(attachInputBoxStyler(this.inputBox, this.themeService));
this.disposables.push(this.inputBox);
this.inputBox.onDidChange(triggerValidation, null, this.disposables);
const onKeyUp = domEvent(this.inputBox.inputElement, 'keyup');
const onMouseUp = domEvent(this.inputBox.inputElement, 'mouseup');
anyEvent<any>(onKeyUp, onMouseUp)(triggerValidation, null, this.disposables);
this.inputBox.value = this.repository.input.value;
this.inputBox.onDidChange(value => this.repository.input.value = value, null, this.disposables);
this.repository.input.onDidChange(value => this.inputBox.value = value, null, this.disposables);
updatePlaceholder();
this.repository.input.onDidChangePlaceholder(updatePlaceholder, null, this.disposables);
this.keybindingService.onDidUpdateKeybindings(updatePlaceholder, null, this.disposables);
this.disposables.push(this.inputBox.onDidHeightChange(() => this.layoutBody()));
if (this.repository.provider.onDidChangeCommitTemplate) {
this.repository.provider.onDidChangeCommitTemplate(this.updateInputBox, this, this.disposables);
}
this.inputBoxContainer = append(container, $('.scm-editor'));
const updatePlaceholder = () => {
const binding = this.keybindingService.lookupKeybinding('scm.acceptInput');
const label = binding ? binding.getLabel() : (platform.isMacintosh ? 'Cmd+Enter' : 'Ctrl+Enter');
const placeholder = format(this.repository.input.placeholder, label);
this.inputBox.setPlaceHolder(placeholder);
};
const validationDelayer = new ThrottledDelayer<any>(200);
const validate = () => {
return this.repository.input.validateInput(this.inputBox.value, this.inputBox.inputElement.selectionStart).then(result => {
if (!result) {
this.inputBox.inputElement.removeAttribute('aria-invalid');
this.inputBox.hideMessage();
} else {
this.inputBox.inputElement.setAttribute('aria-invalid', 'true');
this.inputBox.showMessage({ content: result.message, type: convertValidationType(result.type) });
}
});
};
const triggerValidation = () => validationDelayer.trigger(validate);
this.inputBox = new InputBox(this.inputBoxContainer, this.contextViewService, { flexibleHeight: true });
this.disposables.push(attachInputBoxStyler(this.inputBox, this.themeService));
this.disposables.push(this.inputBox);
this.inputBox.onDidChange(triggerValidation, null, this.disposables);
const onKeyUp = domEvent(this.inputBox.inputElement, 'keyup');
const onMouseUp = domEvent(this.inputBox.inputElement, 'mouseup');
anyEvent<any>(onKeyUp, onMouseUp)(triggerValidation, null, this.disposables);
this.inputBox.value = this.repository.input.value;
this.inputBox.onDidChange(value => this.repository.input.value = value, null, this.disposables);
this.repository.input.onDidChange(value => this.inputBox.value = value, null, this.disposables);
this.updateInputBox();
updatePlaceholder();
this.repository.input.onDidChangePlaceholder(updatePlaceholder, null, this.disposables);
this.keybindingService.onDidUpdateKeybindings(updatePlaceholder, null, this.disposables);
this.disposables.push(this.inputBox.onDidHeightChange(() => this.layoutBody()));
if (this.repository.provider.onDidChangeCommitTemplate) {
this.repository.provider.onDidChangeCommitTemplate(this.updateInputBox, this, this.disposables);
}
this.updateInputBox();
// Input box visibility
this.repository.input.onDidChangeVisibility(this.updateInputBoxVisibility, this, this.disposables);
this.updateInputBoxVisibility();
// List
this.listContainer = append(container, $('.scm-status.show-file-icons'));
......@@ -920,25 +922,35 @@ export class RepositoryPanel extends ViewletPanel {
}
this.cachedHeight = height;
if (this.inputBox) {
if (this.repository.input.visible) {
removeClass(this.inputBoxContainer, 'hidden');
this.inputBox.layout();
}
const editorHeight = this.inputBox ? this.inputBox.height : 0;
const listHeight = height - (editorHeight + (editorHeight ? 12 : 0) /* margin */);
this.listContainer.style.height = `${listHeight}px`;
this.list.layout(listHeight);
const editorHeight = this.inputBox.height;
const listHeight = height - (editorHeight + 12 /* margin */);
this.listContainer.style.height = `${listHeight}px`;
this.list.layout(listHeight);
if (this.inputBoxContainer) {
toggleClass(this.inputBoxContainer, 'scroll', editorHeight >= 134);
} else {
addClass(this.inputBoxContainer, 'hidden');
removeClass(this.inputBoxContainer, 'scroll');
this.listContainer.style.height = `${height}px`;
this.list.layout(height);
}
}
focus(): void {
super.focus();
if (this.isExpanded() && this.inputBox) {
this.inputBox.focus();
if (this.isExpanded()) {
if (this.repository.input.visible) {
this.inputBox.focus();
} else {
this.list.domFocus();
}
}
}
......@@ -997,13 +1009,19 @@ export class RepositoryPanel extends ViewletPanel {
}
private updateInputBox(): void {
if (typeof this.repository.provider.commitTemplate === 'undefined' || !this.inputBox || this.inputBox.value) {
if (typeof this.repository.provider.commitTemplate === 'undefined' || !this.repository.input.visible || this.inputBox.value) {
return;
}
this.inputBox.value = this.repository.provider.commitTemplate;
}
private updateInputBoxVisibility(): void {
if (this.cachedHeight) {
this.layoutBody(this.cachedHeight);
}
}
dispose(): void {
this.visibilityDisposables = dispose(this.visibilityDisposables);
super.dispose();
......
......@@ -63,8 +63,6 @@ export interface ISCMProvider extends IDisposable {
readonly statusBarCommands?: Command[];
readonly onDidChange: Event<void>;
readonly hideInputBox?: boolean | undefined;
getOriginalResource(uri: URI): TPromise<URI>;
}
......@@ -92,6 +90,9 @@ export interface ISCMInput {
validateInput: IInputValidator;
readonly onDidChangeValidateInput: Event<void>;
visible: boolean;
readonly onDidChangeVisibility: Event<boolean>;
}
export interface ISCMRepository extends IDisposable {
......
......@@ -40,6 +40,20 @@ class SCMInput implements ISCMInput {
private _onDidChangePlaceholder = new Emitter<string>();
get onDidChangePlaceholder(): Event<string> { return this._onDidChangePlaceholder.event; }
private _visible = true;
get visible(): boolean {
return this._visible;
}
set visible(visible: boolean) {
this._visible = visible;
this._onDidChangeVisibility.fire(visible);
}
private _onDidChangeVisibility = new Emitter<boolean>();
get onDidChangeVisibility(): Event<boolean> { return this._onDidChangeVisibility.event; }
private _validateInput: IInputValidator = () => TPromise.as(undefined);
get validateInput(): IInputValidator {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册