* add custom hover for quick open

* 💄

* 💄

* adjust delayer create logic
This commit is contained in:
Hans 2023-08-30 09:04:15 +08:00 коммит произвёл GitHub
Родитель 20f0091347
Коммит 046cfbf6d0
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
4 изменённых файлов: 51 добавлений и 50 удалений

Просмотреть файл

@ -47,7 +47,7 @@ export interface IQuickInputOptions {
renderers: IListRenderer<T, any>[],
options: IListOptions<T>,
): List<T>;
hoverDelegate: IHoverDelegate;
hoverDelegate?: IHoverDelegate;
styles: IQuickInputStyles;
}

Просмотреть файл

@ -83,12 +83,13 @@ export class QuickInputController extends Disposable {
const titleBar = dom.append(container, $('.quick-input-titlebar'));
const leftActionBar = this._register(new ActionBar(titleBar));
const actionBarOption = this.options.hoverDelegate ? { hoverDelegate: this.options.hoverDelegate } : undefined;
const leftActionBar = this._register(new ActionBar(titleBar, actionBarOption));
leftActionBar.domNode.classList.add('quick-input-left-action-bar');
const title = dom.append(titleBar, $('.quick-input-title'));
const rightActionBar = this._register(new ActionBar(titleBar));
const rightActionBar = this._register(new ActionBar(titleBar, actionBarOption));
rightActionBar.domNode.classList.add('quick-input-right-action-bar');
const headerContainer = dom.append(container, $('.quick-input-header'));

Просмотреть файл

@ -541,46 +541,49 @@ export class QuickInputList {
}
}));
const delayer = new ThrottledDelayer(options.hoverDelegate.delay);
// onMouseOver triggers every time a new element has been moused over
// even if it's on the same list item.
this.disposables.push(this.list.onMouseOver(async e => {
// If we hover over an anchor element, we don't want to show the hover because
// the anchor may have a tooltip that we want to show instead.
if (e.browserEvent.target instanceof HTMLAnchorElement) {
delayer.cancel();
return;
}
if (
// anchors are an exception as called out above so we skip them here
!(e.browserEvent.relatedTarget instanceof HTMLAnchorElement) &&
// check if the mouse is still over the same element
dom.isAncestor(e.browserEvent.relatedTarget as Node, e.element?.element as Node)
) {
return;
}
try {
await delayer.trigger(async () => {
if (e.element) {
this.showHover(e.element);
}
});
} catch (e) {
// Ignore cancellation errors due to mouse out
if (!isCancellationError(e)) {
throw e;
if (options.hoverDelegate) {
const delayer = new ThrottledDelayer(options.hoverDelegate.delay);
// onMouseOver triggers every time a new element has been moused over
// even if it's on the same list item.
this.disposables.push(this.list.onMouseOver(async e => {
// If we hover over an anchor element, we don't want to show the hover because
// the anchor may have a tooltip that we want to show instead.
if (e.browserEvent.target instanceof HTMLAnchorElement) {
delayer.cancel();
return;
}
}
}));
this.disposables.push(this.list.onMouseOut(e => {
// onMouseOut triggers every time a new element has been moused over
// even if it's on the same list item. We only want one event, so we
// check if the mouse is still over the same element.
if (dom.isAncestor(e.browserEvent.relatedTarget as Node, e.element?.element as Node)) {
return;
}
delayer.cancel();
}));
if (
// anchors are an exception as called out above so we skip them here
!(e.browserEvent.relatedTarget instanceof HTMLAnchorElement) &&
// check if the mouse is still over the same element
dom.isAncestor(e.browserEvent.relatedTarget as Node, e.element?.element as Node)
) {
return;
}
try {
await delayer.trigger(async () => {
if (e.element) {
this.showHover(e.element);
}
});
} catch (e) {
// Ignore cancellation errors due to mouse out
if (!isCancellationError(e)) {
throw e;
}
}
}));
this.disposables.push(this.list.onMouseOut(e => {
// onMouseOut triggers every time a new element has been moused over
// even if it's on the same list item. We only want one event, so we
// check if the mouse is still over the same element.
if (dom.isAncestor(e.browserEvent.relatedTarget as Node, e.element?.element as Node)) {
return;
}
delayer.cancel();
}));
this.disposables.push(delayer);
}
this.disposables.push(this._listElementChecked.event(_ => this.fireCheckedEvents()));
this.disposables.push(
this._onChangedAllVisibleChecked,
@ -590,8 +593,7 @@ export class QuickInputList {
this._onButtonTriggered,
this._onSeparatorButtonTriggered,
this._onLeave,
this._onKeyDown,
delayer
this._onKeyDown
);
}
@ -839,10 +841,14 @@ export class QuickInputList {
* @param element The element to show the hover for
*/
private showHover(element: IListElement): void {
if (this.options.hoverDelegate === undefined) {
return;
}
if (this._lastHover && !this._lastHover.isDisposed) {
this.options.hoverDelegate.onDidHideHover?.();
this._lastHover?.dispose();
}
if (!element.element || !element.saneTooltip) {
return;
}

Просмотреть файл

@ -86,12 +86,6 @@ export class QuickInputService extends Themable implements IQuickInputService {
renderers: IListRenderer<T, any>[],
options: IWorkbenchListOptions<T>
) => this.instantiationService.createInstance(WorkbenchList, user, container, delegate, renderers, options) as List<T>,
hoverDelegate: {
showHover(options, focus) {
return undefined;
},
delay: 200
},
styles: this.computeStyles()
};