提交 42a38fb1 编写于 作者: R rebornix

Fix #5525. Scroll beyond first line to avoid Find Widget covering anything

上级 b5fff271
......@@ -17,7 +17,7 @@ import { FindInput, IFindInputStyles } from 'vs/base/browser/ui/findinput/findIn
import { IMessage as InputBoxMessage, InputBox } from 'vs/base/browser/ui/inputbox/inputBox';
import { Widget } from 'vs/base/browser/ui/widget';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { ICodeEditor, IOverlayWidget, IOverlayWidgetPosition, OverlayWidgetPositionPreference } from 'vs/editor/browser/editorBrowser';
import { ICodeEditor, IOverlayWidget, IOverlayWidgetPosition, IViewZone, OverlayWidgetPositionPreference } from 'vs/editor/browser/editorBrowser';
import { FIND_IDS, MATCHES_LIMIT } from 'vs/editor/contrib/find/common/findModel';
import { FindReplaceState, FindReplaceStateChangedEvent } from 'vs/editor/contrib/find/common/findState';
import { Range } from 'vs/editor/common/core/range';
......@@ -51,12 +51,31 @@ const NLS_NO_RESULTS = nls.localize('label.noResults', "No Results");
let MAX_MATCHES_COUNT_WIDTH = 69;
const WIDGET_FIXED_WIDTH = 411 - 69;
export class FindWidgetViewZone implements IViewZone {
public afterLineNumber: number;
public heightInPx: number;
public suppressMouseDown: boolean;
public domNode: HTMLElement;
constructor(afterLineNumber: number) {
this.afterLineNumber = afterLineNumber;
this.heightInPx = 34;
this.suppressMouseDown = false;
this.domNode = document.createElement('div');
this.domNode.className = 'dock-find-viewzone';
}
}
export class FindWidget extends Widget implements IOverlayWidget {
private static ID = 'editor.contrib.findWidget';
private static PART_WIDTH = 275;
private static FIND_INPUT_AREA_WIDTH = FindWidget.PART_WIDTH - 54;
private static REPLACE_INPUT_AREA_WIDTH = FindWidget.FIND_INPUT_AREA_WIDTH;
private static FIND_INPUT_AREA_HEIGHT = 34; // The height of Find Widget when Replace Input is not visible.
private static FIND_REPLACE_AREA_HEIGHT = 64; // The height of Find Widget when Replace Input is visible.
private _codeEditor: ICodeEditor;
private _state: FindReplaceState;
......@@ -82,6 +101,8 @@ export class FindWidget extends Widget implements IOverlayWidget {
private _focusTracker: dom.IFocusTracker;
private _findInputFocussed: IContextKey<boolean>;
private _viewZone: FindWidgetViewZone;
private _viewZoneId: number;
constructor(
codeEditor: ICodeEditor,
......@@ -169,9 +190,29 @@ export class FindWidget extends Widget implements IOverlayWidget {
});
this._codeEditor.addOverlayWidget(this);
this._viewZone = new FindWidgetViewZone(0); // Put it before the first line then users can scroll beyond the first line.
this._applyTheme(themeService.getTheme());
this._register(themeService.onThemeChange(this._applyTheme.bind(this)));
this._register(this._codeEditor.onDidChangeModel((e) => {
if (!this._isVisible) {
return;
}
if (this._viewZoneId === undefined) {
return;
}
this._codeEditor.changeViewZones((accessor) => {
accessor.removeZone(this._viewZoneId);
this._viewZoneId = undefined;
});
}));
this._register(this._codeEditor.onDidScrollChange((e) => {
this._layoutViewZone();
}));
}
// ----- IOverlayWidget API
......@@ -246,6 +287,9 @@ export class FindWidget extends Widget implements IOverlayWidget {
this._updateMatchesCount();
}
if (e.searchString || e.currentMatch) {
this._layoutViewZone();
}
}
private _updateMatchesCount(): void {
......@@ -331,6 +375,7 @@ export class FindWidget extends Widget implements IOverlayWidget {
}
}, 0);
this._codeEditor.layoutOverlayWidget(this);
this._showViewZone();
}
}
......@@ -345,7 +390,60 @@ export class FindWidget extends Widget implements IOverlayWidget {
this._codeEditor.focus();
}
this._codeEditor.layoutOverlayWidget(this);
this._codeEditor.changeViewZones((accessor) => {
if (this._viewZoneId !== undefined) {
accessor.removeZone(this._viewZoneId);
this._viewZoneId = undefined;
this._codeEditor.setScrollTop(this._codeEditor.getScrollTop() - this._viewZone.heightInPx);
}
});
}
}
private _layoutViewZone() {
if (!this._isVisible) {
return;
}
if (this._viewZoneId !== undefined) {
return;
}
this._codeEditor.changeViewZones((accessor) => {
if (this._state.isReplaceRevealed) {
this._viewZone.heightInPx = FindWidget.FIND_REPLACE_AREA_HEIGHT;
} else {
this._viewZone.heightInPx = FindWidget.FIND_INPUT_AREA_HEIGHT;
}
this._viewZoneId = accessor.addZone(this._viewZone);
this._codeEditor.setScrollTop(this._codeEditor.getScrollTop() + this._viewZone.heightInPx);
});
}
private _showViewZone() {
if (!this._isVisible) {
return;
}
this._codeEditor.changeViewZones((accessor) => {
let scrollAdjustment = FindWidget.FIND_INPUT_AREA_HEIGHT;
if (this._viewZoneId !== undefined) {
if (this._state.isReplaceRevealed) {
this._viewZone.heightInPx = FindWidget.FIND_REPLACE_AREA_HEIGHT;
scrollAdjustment = FindWidget.FIND_REPLACE_AREA_HEIGHT - FindWidget.FIND_INPUT_AREA_HEIGHT;
} else {
this._viewZone.heightInPx = FindWidget.FIND_INPUT_AREA_HEIGHT;
scrollAdjustment = FindWidget.FIND_INPUT_AREA_HEIGHT - FindWidget.FIND_REPLACE_AREA_HEIGHT;
}
accessor.removeZone(this._viewZoneId);
} else {
this._viewZone.heightInPx = FindWidget.FIND_INPUT_AREA_HEIGHT;
}
this._viewZoneId = accessor.addZone(this._viewZone);
this._codeEditor.setScrollTop(this._codeEditor.getScrollTop() + scrollAdjustment);
});
}
private _applyTheme(theme: ITheme) {
......@@ -644,6 +742,7 @@ export class FindWidget extends Widget implements IOverlayWidget {
className: 'toggle left',
onTrigger: () => {
this._state.change({ isReplaceRevealed: !this._isReplaceVisible }, false);
this._showViewZone();
},
onKeyDown: (e) => { }
}));
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册