提交 65d5eb56 编写于 作者: C Christof Marti

Label, description, detail (#45589)

上级 60729e01
......@@ -17,6 +17,7 @@ export class MainThreadQuickOpen implements MainThreadQuickOpenShape {
private _proxy: ExtHostQuickOpenShape;
private _quickOpenService: IQuickOpenService;
private _quickInputService: IQuickInputService;
private _doSetItems: (items: MyQuickPickItems[]) => any;
private _doSetError: (error: Error) => any;
private _contents: TPromise<MyQuickPickItems[]>;
......@@ -25,10 +26,11 @@ export class MainThreadQuickOpen implements MainThreadQuickOpenShape {
constructor(
extHostContext: IExtHostContext,
@IQuickOpenService quickOpenService: IQuickOpenService,
@IQuickInputService private _quickInputService: IQuickInputService
@IQuickInputService quickInputService: IQuickInputService
) {
this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostQuickOpen);
this._quickOpenService = quickOpenService;
this._quickInputService = quickInputService;
}
public dispose(): void {
......
......@@ -22,7 +22,7 @@
}
.quick-input-box .monaco-inputbox > .wrapper > .input {
padding-left: 14px;
padding-left: 15px;
}
.quick-input-action {
......@@ -37,4 +37,47 @@
.quick-input-checkbox-list {
margin-left: 3px;
line-height: 22px;
}
.quick-input-checkbox-list .quick-input-checkbox-list-entry {
overflow: hidden;
display: flex;
height: 100%;
}
.quick-input-checkbox-list .quick-input-checkbox-list-label {
overflow: hidden;
display: flex;
height: 100%;
flex: 1;
}
.quick-input-checkbox-list .quick-input-checkbox-list-checkbox {
align-self: center;
/* margin-top: 5px; */
}
.quick-input-checkbox-list .quick-input-checkbox-list-rows {
overflow: hidden;
text-overflow: ellipsis;
display: flex;
flex-direction: column;
height: 100%;
flex: 1;
margin-left: 1px;
}
.quick-input-checkbox-list .quick-input-checkbox-list-rows > .quick-input-checkbox-list-row {
display: flex;
align-items: center;
}
.quick-input-checkbox-list .quick-input-checkbox-list-rows .monaco-highlighted-label span {
opacity: 1;
}
.quick-input-checkbox-list .quick-input-checkbox-list-label-meta {
opacity: 0.7;
line-height: normal;
}
......@@ -23,6 +23,8 @@ import { QuickInputBox } from './quickInputBox';
import { KeyCode } from 'vs/base/common/keyCodes';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { localize } from 'vs/nls';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { CLOSE_ON_FOCUS_LOST_CONFIG } from 'vs/workbench/browser/quickopen';
const $ = dom.$;
......@@ -42,6 +44,7 @@ export class QuickInputService extends Component implements IQuickInputService {
private resolve: (value?: object[] | Thenable<object[]>) => void;
constructor(
@IConfigurationService private configurationService: IConfigurationService,
@IInstantiationService private instantiationService: IInstantiationService,
@IPartService private partService: IPartService,
@IThemeService themeService: IThemeService
......@@ -63,7 +66,7 @@ export class QuickInputService extends Component implements IQuickInputService {
this.inputBox = new QuickInputBox(headerContainer);
this.toUnbind.push(this.inputBox);
this.inputBox.style(this.themeService.getTheme());
this.inputBox.onInput(value => {
this.inputBox.onDidChange(value => {
this.checkboxList.filter(value);
});
this.toUnbind.push(this.inputBox.onKeyDown(event => {
......@@ -101,7 +104,9 @@ export class QuickInputService extends Component implements IQuickInputService {
return;
}
}
this.close(false);
if (this.configurationService.getValue(CLOSE_ON_FOCUS_LOST_CONFIG)) {
this.close(false);
}
}));
this.toUnbind.push(dom.addDisposableListener(this.container, dom.EventType.KEY_DOWN, (e: KeyboardEvent) => {
const event = new StandardKeyboardEvent(e);
......@@ -130,9 +135,10 @@ export class QuickInputService extends Component implements IQuickInputService {
async pick<T extends IPickOpenEntry>(picks: TPromise<T[]>, options?: IPickOptions, token?: CancellationToken): TPromise<T[]> {
this.create();
if (this.resolve) {
this.resolve(undefined);
this.resolve();
}
this.inputBox.setValue('');
this.inputBox.setPlaceholder(options.placeHolder || '');
// TODO: Progress indication.
this.checkboxList.setElements(await picks);
......
......@@ -46,10 +46,14 @@ export class QuickInputBox {
});
}
onInput(handler: (event: string) => void): IDisposable {
onDidChange(handler: (event: string) => void): IDisposable {
return this.inputBox.onDidChange(handler);
}
setValue(value: string) {
this.inputBox.value = value;
}
setPlaceholder(placeholder: string) {
this.inputBox.setPlaceHolder(placeholder);
}
......
......@@ -19,20 +19,20 @@ import { Emitter } from 'vs/base/common/event';
import { assign } from 'vs/base/common/objects';
import { KeyCode } from 'vs/base/common/keyCodes';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { IconLabel, IIconLabelValueOptions } from 'vs/base/browser/ui/iconLabel/iconLabel';
import { HighlightedLabel } from 'vs/base/browser/ui/highlightedlabel/highlightedLabel';
const $ = dom.$;
interface ISelectableElement {
index: number;
item: object;
label: string;
item: IPickOpenEntry;
selected: boolean;
}
class SelectableElement implements ISelectableElement {
index: number;
item: object;
label: string;
item: IPickOpenEntry;
shouldAlwaysShow = false;
hidden = false;
private _onSelected = new Emitter<boolean>();
......@@ -57,10 +57,10 @@ class SelectableElement implements ISelectableElement {
}
interface ISelectedElementTemplateData {
element: HTMLElement;
name: HTMLElement;
checkbox: HTMLInputElement;
context: SelectableElement;
label: IconLabel;
detail: HighlightedLabel;
element: SelectableElement;
toDisposeElement: IDisposable[];
toDisposeTemplate: IDisposable[];
}
......@@ -75,30 +75,50 @@ class SelectedElementRenderer implements IRenderer<SelectableElement, ISelectedE
renderTemplate(container: HTMLElement): ISelectedElementTemplateData {
const data: ISelectedElementTemplateData = Object.create(null);
data.element = dom.append(container, $('.selected_element'));
data.checkbox = <HTMLInputElement>$('input');
const entry = dom.append(container, $('.quick-input-checkbox-list-entry'));
const label = dom.append(entry, $('label.quick-input-checkbox-list-label'));
// Entry
data.checkbox = <HTMLInputElement>dom.append(label, $('input.quick-input-checkbox-list-checkbox'));
data.checkbox.type = 'checkbox';
data.toDisposeElement = [];
data.toDisposeTemplate = [];
data.toDisposeTemplate.push(dom.addStandardDisposableListener(data.checkbox, dom.EventType.CHANGE, e => {
data.context.selected = data.checkbox.checked;
data.element.selected = data.checkbox.checked;
}));
dom.append(data.element, data.checkbox);
const rows = dom.append(label, $('.quick-input-checkbox-list-rows'));
const row1 = dom.append(rows, $('.quick-input-checkbox-list-row'));
const row2 = dom.append(rows, $('.quick-input-checkbox-list-row'));
// Label
data.label = new IconLabel(row1, { supportHighlights: true, supportDescriptionHighlights: true });
data.name = dom.append(data.element, $('span.label'));
// Detail
const detailContainer = dom.append(row2, $('.quick-input-checkbox-list-label-meta'));
data.detail = new HighlightedLabel(detailContainer);
return data;
}
renderElement(element: SelectableElement, index: number, data: ISelectedElementTemplateData): void {
dispose(data.toDisposeElement);
data.context = element;
data.name.textContent = element.label;
data.element.title = data.name.textContent;
data.element = element;
data.checkbox.checked = element.selected;
data.toDisposeElement.push(element.onSelected(selected => data.checkbox.checked = selected));
const { labelHighlights, descriptionHighlights, detailHighlights } = element;
// Label
const options: IIconLabelValueOptions = Object.create(null);
options.matches = labelHighlights || [];
options.descriptionTitle = element.item.description;
options.descriptionMatches = descriptionHighlights || [];
data.label.setValue(element.item.label, element.item.description, options);
// Meta
data.detail.set(element.item.detail, detailHighlights);
}
disposeTemplate(data: ISelectedElementTemplateData): void {
......@@ -109,7 +129,7 @@ class SelectedElementRenderer implements IRenderer<SelectableElement, ISelectedE
class SelectedElementDelegate implements IDelegate<SelectableElement> {
getHeight(element: SelectableElement): number {
return 22;
return element.item.detail ? 44 : 22;
}
getTemplateId(element: SelectableElement): string {
......@@ -147,10 +167,10 @@ export class QuickInputCheckboxList {
this.elements = elements.map((item, index) => new SelectableElement({
index,
item,
label: item.label,
selected: !!item.selected
}));
this.list.splice(0, this.list.length, this.elements);
this.list.focusFirst();
}
getSelectedElements() {
......@@ -182,9 +202,9 @@ export class QuickInputCheckboxList {
// Filter by value (since we support octicons, use octicon aware fuzzy matching)
else {
this.elements.forEach(element => {
const labelHighlights = matchesFuzzyOcticonAware(query, parseOcticons(element.label));
const descriptionHighlights = undefined; // TODO matchesFuzzyOcticonAware(query, parseOcticons(element.description));
const detailHighlights = undefined; // TODO matchesFuzzyOcticonAware(query, parseOcticons(element.detail));
const labelHighlights = matchesFuzzyOcticonAware(query, parseOcticons(element.item.label));
const descriptionHighlights = matchesFuzzyOcticonAware(query, parseOcticons(element.item.description || ''));
const detailHighlights = matchesFuzzyOcticonAware(query, parseOcticons(element.item.detail || ''));
if (element.shouldAlwaysShow || labelHighlights || descriptionHighlights || detailHighlights) {
element.labelHighlights = labelHighlights;
......@@ -211,9 +231,7 @@ export class QuickInputCheckboxList {
this.list.splice(0, this.list.length, this.elements.filter(element => !element.hidden));
this.list.layout();
if (query) {
this.list.focusFirst();
}
this.list.focusFirst();
}
toggleCheckbox() {
......@@ -240,5 +258,5 @@ function compareEntries(elementA: SelectableElement, elementB: SelectableElement
return 1;
}
return compareAnything(elementA.label, elementB.label, lookFor);
return compareAnything(elementA.item.label, elementB.item.label, lookFor);
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册