Skip to content

Commit

Permalink
Label, description, detail (#45589)
Browse files Browse the repository at this point in the history
  • Loading branch information
chrmarti committed Mar 26, 2018
1 parent 60729e0 commit 65d5eb5
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 30 deletions.
4 changes: 3 additions & 1 deletion src/vs/workbench/api/electron-browser/mainThreadQuickOpen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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[]>;
Expand All @@ -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 {
Expand Down
45 changes: 44 additions & 1 deletion src/vs/workbench/browser/parts/quickinput/quickInput.css
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
}

.quick-input-box .monaco-inputbox > .wrapper > .input {
padding-left: 14px;
padding-left: 15px;
}

.quick-input-action {
Expand All @@ -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;
}
12 changes: 9 additions & 3 deletions src/vs/workbench/browser/parts/quickinput/quickInput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.$;

Expand All @@ -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
Expand All @@ -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 => {
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
6 changes: 5 additions & 1 deletion src/vs/workbench/browser/parts/quickinput/quickInputBox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
66 changes: 42 additions & 24 deletions src/vs/workbench/browser/parts/quickinput/quickInputCheckboxList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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>();
Expand All @@ -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[];
}
Expand All @@ -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 {
Expand All @@ -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 {
Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -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;
Expand All @@ -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() {
Expand All @@ -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);
}

0 comments on commit 65d5eb5

Please sign in to comment.