initial support of QuickPickItemButton API (#130519)
This commit is contained in:
parent
0344ecd462
commit
4191923874
14
src/vs/vscode.proposed.d.ts
vendored
14
src/vs/vscode.proposed.d.ts
vendored
|
@ -2796,4 +2796,18 @@ declare module 'vscode' {
|
|||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region https://github.com/microsoft/vscode/issues/88716
|
||||
export interface QuickPickItem {
|
||||
buttons?: QuickInputButton[];
|
||||
}
|
||||
export interface QuickPick<T extends QuickPickItem> extends QuickInput {
|
||||
readonly onDidTriggerItemButton: Event<QuickPickItemButtonEvent<T>>;
|
||||
}
|
||||
export interface QuickPickItemButtonEvent<T extends QuickPickItem> {
|
||||
button: QuickInputButton;
|
||||
item: T;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
}
|
||||
|
|
|
@ -3,18 +3,24 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IPickOptions, IInputOptions, IQuickInputService, IQuickInput } from 'vs/platform/quickinput/common/quickInput';
|
||||
import { IPickOptions, IInputOptions, IQuickInputService, IQuickInput, IQuickPick, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput';
|
||||
import { ExtHostContext, MainThreadQuickOpenShape, ExtHostQuickOpenShape, TransferQuickPickItems, MainContext, IExtHostContext, TransferQuickInput, TransferQuickInputButton, IInputBoxOptions } from 'vs/workbench/api/common/extHost.protocol';
|
||||
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { ThemeIcon } from 'vs/platform/theme/common/themeService';
|
||||
|
||||
interface QuickInputSession {
|
||||
input: IQuickInput;
|
||||
handlesToItems: Map<number, TransferQuickPickItems>;
|
||||
}
|
||||
|
||||
function reviveIconPathUris(iconPath: { dark: URI; light?: URI | undefined; }) {
|
||||
iconPath.dark = URI.revive(iconPath.dark);
|
||||
if (iconPath.light) {
|
||||
iconPath.light = URI.revive(iconPath.light);
|
||||
}
|
||||
}
|
||||
|
||||
@extHostNamedCustomer(MainContext.MainThreadQuickOpen)
|
||||
export class MainThreadQuickOpen implements MainThreadQuickOpenShape {
|
||||
|
||||
|
@ -115,49 +121,39 @@ export class MainThreadQuickOpen implements MainThreadQuickOpenShape {
|
|||
const sessionId = params.id;
|
||||
let session = this.sessions.get(sessionId);
|
||||
if (!session) {
|
||||
|
||||
const input = params.type === 'quickPick' ? this._quickInputService.createQuickPick() : this._quickInputService.createInputBox();
|
||||
input.onDidAccept(() => {
|
||||
this._proxy.$onDidAccept(sessionId);
|
||||
});
|
||||
input.onDidTriggerButton(button => {
|
||||
this._proxy.$onDidTriggerButton(sessionId, (button as TransferQuickInputButton).handle);
|
||||
});
|
||||
input.onDidChangeValue(value => {
|
||||
this._proxy.$onDidChangeValue(sessionId, value);
|
||||
});
|
||||
input.onDidHide(() => {
|
||||
this._proxy.$onDidHide(sessionId);
|
||||
});
|
||||
|
||||
if (params.type === 'quickPick') {
|
||||
const input = this._quickInputService.createQuickPick();
|
||||
input.onDidAccept(() => {
|
||||
this._proxy.$onDidAccept(sessionId);
|
||||
});
|
||||
input.onDidChangeActive(items => {
|
||||
// Add extra events specific for quickpick
|
||||
const quickpick = input as IQuickPick<IQuickPickItem>;
|
||||
quickpick.onDidChangeActive(items => {
|
||||
this._proxy.$onDidChangeActive(sessionId, items.map(item => (item as TransferQuickPickItems).handle));
|
||||
});
|
||||
input.onDidChangeSelection(items => {
|
||||
quickpick.onDidChangeSelection(items => {
|
||||
this._proxy.$onDidChangeSelection(sessionId, items.map(item => (item as TransferQuickPickItems).handle));
|
||||
});
|
||||
input.onDidTriggerButton(button => {
|
||||
this._proxy.$onDidTriggerButton(sessionId, (button as TransferQuickInputButton).handle);
|
||||
quickpick.onDidTriggerItemButton((e) => {
|
||||
this._proxy.$onDidTriggerItemButton(sessionId, (e.item as TransferQuickPickItems).handle, (e.button as TransferQuickInputButton).handle);
|
||||
});
|
||||
input.onDidChangeValue(value => {
|
||||
this._proxy.$onDidChangeValue(sessionId, value);
|
||||
});
|
||||
input.onDidHide(() => {
|
||||
this._proxy.$onDidHide(sessionId);
|
||||
});
|
||||
session = {
|
||||
input,
|
||||
handlesToItems: new Map()
|
||||
};
|
||||
} else {
|
||||
const input = this._quickInputService.createInputBox();
|
||||
input.onDidAccept(() => {
|
||||
this._proxy.$onDidAccept(sessionId);
|
||||
});
|
||||
input.onDidTriggerButton(button => {
|
||||
this._proxy.$onDidTriggerButton(sessionId, (button as TransferQuickInputButton).handle);
|
||||
});
|
||||
input.onDidChangeValue(value => {
|
||||
this._proxy.$onDidChangeValue(sessionId, value);
|
||||
});
|
||||
input.onDidHide(() => {
|
||||
this._proxy.$onDidHide(sessionId);
|
||||
});
|
||||
session = {
|
||||
input,
|
||||
handlesToItems: new Map()
|
||||
};
|
||||
}
|
||||
|
||||
session = {
|
||||
input,
|
||||
handlesToItems: new Map()
|
||||
};
|
||||
this.sessions.set(sessionId, session);
|
||||
}
|
||||
const { input, handlesToItems } = session;
|
||||
|
@ -174,6 +170,15 @@ export class MainThreadQuickOpen implements MainThreadQuickOpenShape {
|
|||
} else if (param === 'items') {
|
||||
handlesToItems.clear();
|
||||
params[param].forEach((item: TransferQuickPickItems) => {
|
||||
if (item.buttons) {
|
||||
item.buttons = item.buttons.map((button: TransferQuickInputButton) => {
|
||||
if (button.iconPath) {
|
||||
reviveIconPathUris(button.iconPath);
|
||||
}
|
||||
|
||||
return button;
|
||||
});
|
||||
}
|
||||
handlesToItems.set(item.handle, item);
|
||||
});
|
||||
(input as any)[param] = params[param];
|
||||
|
@ -186,23 +191,12 @@ export class MainThreadQuickOpen implements MainThreadQuickOpenShape {
|
|||
if (button.handle === -1) {
|
||||
return this._quickInputService.backButton;
|
||||
}
|
||||
const { iconPath, tooltip, handle } = button;
|
||||
if ('id' in iconPath) {
|
||||
return {
|
||||
iconClass: ThemeIcon.asClassName(iconPath),
|
||||
tooltip,
|
||||
handle
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
iconPath: {
|
||||
dark: URI.revive(iconPath.dark),
|
||||
light: iconPath.light && URI.revive(iconPath.light)
|
||||
},
|
||||
tooltip,
|
||||
handle
|
||||
};
|
||||
|
||||
if (button.iconPath) {
|
||||
reviveIconPathUris(button.iconPath);
|
||||
}
|
||||
|
||||
return button;
|
||||
});
|
||||
} else {
|
||||
(input as any)[param] = params[param];
|
||||
|
|
|
@ -516,12 +516,11 @@ export interface MainThreadTerminalServiceShape extends IDisposable {
|
|||
|
||||
export interface TransferQuickPickItems extends quickInput.IQuickPickItem {
|
||||
handle: number;
|
||||
buttons?: TransferQuickInputButton[];
|
||||
}
|
||||
|
||||
export interface TransferQuickInputButton {
|
||||
export interface TransferQuickInputButton extends quickInput.IQuickInputButton {
|
||||
handle: number;
|
||||
iconPath: { dark: URI; light?: URI; } | { id: string; };
|
||||
tooltip?: string;
|
||||
}
|
||||
|
||||
export type TransferQuickInput = TransferQuickPick | TransferInputBox;
|
||||
|
@ -1706,6 +1705,7 @@ export interface ExtHostQuickOpenShape {
|
|||
$onDidAccept(sessionId: number): void;
|
||||
$onDidChangeValue(sessionId: number, value: string): void;
|
||||
$onDidTriggerButton(sessionId: number, handle: number): void;
|
||||
$onDidTriggerItemButton(sessionId: number, itemHandle: number, buttonHandle: number): void;
|
||||
$onDidHide(sessionId: number): void;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ import { Emitter } from 'vs/base/common/event';
|
|||
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { ExtHostCommands } from 'vs/workbench/api/common/extHostCommands';
|
||||
import { IExtHostWorkspaceProvider } from 'vs/workbench/api/common/extHostWorkspace';
|
||||
import { InputBox, InputBoxOptions, QuickInput, QuickInputButton, QuickPick, QuickPickItem, QuickPickOptions, WorkspaceFolder, WorkspaceFolderPickOptions } from 'vscode';
|
||||
import { InputBox, InputBoxOptions, QuickInput, QuickInputButton, QuickPick, QuickPickItem, QuickPickItemButtonEvent, QuickPickOptions, WorkspaceFolder, WorkspaceFolderPickOptions } from 'vscode';
|
||||
import { ExtHostQuickOpenShape, IMainContext, MainContext, TransferQuickPickItems, TransferQuickInput, TransferQuickInputButton } from './extHost.protocol';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { ThemeIcon, QuickInputButtons } from 'vs/workbench/api/common/extHostTypes';
|
||||
|
@ -17,6 +17,7 @@ import { isPromiseCanceledError } from 'vs/base/common/errors';
|
|||
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
||||
import { coalesce } from 'vs/base/common/arrays';
|
||||
import Severity from 'vs/base/common/severity';
|
||||
import { ThemeIcon as ThemeIconUtils } from 'vs/platform/theme/common/themeService';
|
||||
|
||||
export type Item = string | QuickPickItem;
|
||||
|
||||
|
@ -238,6 +239,13 @@ export function createExtHostQuickOpen(mainContext: IMainContext, workspace: IEx
|
|||
}
|
||||
}
|
||||
|
||||
$onDidTriggerItemButton(sessionId: number, itemHandle: number, buttonHandle: number): void {
|
||||
const session = this._sessions.get(sessionId);
|
||||
if (session instanceof ExtHostQuickPick) {
|
||||
session._fireDidTriggerItemButton(itemHandle, buttonHandle);
|
||||
}
|
||||
}
|
||||
|
||||
$onDidHide(sessionId: number): void {
|
||||
const session = this._sessions.get(sessionId);
|
||||
if (session) {
|
||||
|
@ -369,11 +377,13 @@ export function createExtHostQuickOpen(mainContext: IMainContext, workspace: IEx
|
|||
this._handlesToButtons.set(handle, button);
|
||||
});
|
||||
this.update({
|
||||
buttons: buttons.map<TransferQuickInputButton>((button, i) => ({
|
||||
iconPath: getIconUris(button.iconPath),
|
||||
tooltip: button.tooltip,
|
||||
handle: button === QuickInputButtons.Back ? -1 : i,
|
||||
}))
|
||||
buttons: buttons.map<TransferQuickInputButton>((button, i) => {
|
||||
return {
|
||||
...getIconPathOrClass(button),
|
||||
tooltip: button.tooltip,
|
||||
handle: button === QuickInputButtons.Back ? -1 : i,
|
||||
};
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -481,6 +491,22 @@ export function createExtHostQuickOpen(mainContext: IMainContext, workspace: IEx
|
|||
return typeof iconPath === 'object' && 'dark' in iconPath ? iconPath.dark : iconPath;
|
||||
}
|
||||
|
||||
function getIconPathOrClass(button: QuickInputButton) {
|
||||
const iconPathOrIconClass = getIconUris(button.iconPath);
|
||||
let iconPath: { dark: URI; light?: URI | undefined; } | undefined;
|
||||
let iconClass: string | undefined;
|
||||
if ('id' in iconPathOrIconClass) {
|
||||
iconClass = ThemeIconUtils.asClassName(iconPathOrIconClass);
|
||||
} else {
|
||||
iconPath = iconPathOrIconClass;
|
||||
}
|
||||
|
||||
return {
|
||||
iconPath,
|
||||
iconClass
|
||||
};
|
||||
}
|
||||
|
||||
class ExtHostQuickPick<T extends QuickPickItem> extends ExtHostQuickInput implements QuickPick<T> {
|
||||
|
||||
private _items: T[] = [];
|
||||
|
@ -494,12 +520,14 @@ export function createExtHostQuickOpen(mainContext: IMainContext, workspace: IEx
|
|||
private readonly _onDidChangeActiveEmitter = new Emitter<T[]>();
|
||||
private _selectedItems: T[] = [];
|
||||
private readonly _onDidChangeSelectionEmitter = new Emitter<T[]>();
|
||||
private readonly _onDidTriggerItemButtonEmitter = new Emitter<QuickPickItemButtonEvent<T>>();
|
||||
|
||||
constructor(extensionId: ExtensionIdentifier, enableProposedApi: boolean, onDispose: () => void) {
|
||||
constructor(extensionId: ExtensionIdentifier, private readonly enableProposedApi: boolean, onDispose: () => void) {
|
||||
super(extensionId, onDispose);
|
||||
this._disposables.push(
|
||||
this._onDidChangeActiveEmitter,
|
||||
this._onDidChangeSelectionEmitter,
|
||||
this._onDidTriggerItemButtonEmitter
|
||||
);
|
||||
this.update({ type: 'quickPick' });
|
||||
}
|
||||
|
@ -523,7 +551,17 @@ export function createExtHostQuickOpen(mainContext: IMainContext, workspace: IEx
|
|||
handle: i,
|
||||
detail: item.detail,
|
||||
picked: item.picked,
|
||||
alwaysShow: item.alwaysShow
|
||||
alwaysShow: item.alwaysShow,
|
||||
// Proposed API only at the moment
|
||||
buttons: item.buttons && this.enableProposedApi
|
||||
? item.buttons.map<TransferQuickInputButton>((button, i) => {
|
||||
return {
|
||||
...getIconPathOrClass(button),
|
||||
tooltip: button.tooltip,
|
||||
handle: i
|
||||
};
|
||||
})
|
||||
: undefined,
|
||||
}))
|
||||
});
|
||||
}
|
||||
|
@ -597,6 +635,22 @@ export function createExtHostQuickOpen(mainContext: IMainContext, workspace: IEx
|
|||
this._selectedItems = items;
|
||||
this._onDidChangeSelectionEmitter.fire(items);
|
||||
}
|
||||
|
||||
onDidTriggerItemButton = this._onDidTriggerItemButtonEmitter.event;
|
||||
|
||||
_fireDidTriggerItemButton(itemHandle: number, buttonHandle: number) {
|
||||
const item = this._handlesToItems.get(itemHandle)!;
|
||||
if (!item || !item.buttons || !item.buttons.length) {
|
||||
return;
|
||||
}
|
||||
const button = item.buttons[buttonHandle];
|
||||
if (button) {
|
||||
this._onDidTriggerItemButtonEmitter.fire({
|
||||
button,
|
||||
item
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ExtHostInputBox extends ExtHostQuickInput implements InputBox {
|
||||
|
|
Loading…
Reference in a new issue