Skip to content

Commit

Permalink
differentiate between revealing and showing a picker, #9418
Browse files Browse the repository at this point in the history
  • Loading branch information
jrieken committed Jul 16, 2018
1 parent 74880d6 commit d1f47a1
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 39 deletions.
31 changes: 16 additions & 15 deletions src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export interface IBreadcrumbsItemEvent {
type: 'select' | 'focus';
item: BreadcrumbsItem;
node: HTMLElement;
payload: any;
}

export class BreadcrumbsWidget {
Expand Down Expand Up @@ -164,23 +165,23 @@ export class BreadcrumbsWidget {
return this._items[this._focusedItemIdx];
}

setFocused(item: BreadcrumbsItem): void {
this._focus(this._items.indexOf(item));
setFocused(item: BreadcrumbsItem, payload?: any): void {
this._focus(this._items.indexOf(item), payload);
}

focusPrev(): any {
focusPrev(payload?: any): any {
if (this._focusedItemIdx > 0) {
this._focus(this._focusedItemIdx - 1);
this._focus(this._focusedItemIdx - 1, payload);
}
}

focusNext(): any {
focusNext(payload?: any): any {
if (this._focusedItemIdx + 1 < this._nodes.length) {
this._focus(this._focusedItemIdx + 1);
this._focus(this._focusedItemIdx + 1, payload);
}
}

private _focus(nth: number): void {
private _focus(nth: number, payload: any): void {
this._focusedItemIdx = -1;
for (let i = 0; i < this._nodes.length; i++) {
const node = this._nodes[i];
Expand All @@ -192,7 +193,7 @@ export class BreadcrumbsWidget {
}
}
this._reveal(this._focusedItemIdx);
this._onDidFocusItem.fire({ type: 'focus', item: this._items[this._focusedItemIdx], node: this._nodes[this._focusedItemIdx] });
this._onDidFocusItem.fire({ type: 'focus', item: this._items[this._focusedItemIdx], node: this._nodes[this._focusedItemIdx], payload });
}

reveal(item: BreadcrumbsItem): void {
Expand All @@ -213,11 +214,11 @@ export class BreadcrumbsWidget {
return this._items[this._selectedItemIdx];
}

setSelection(item: BreadcrumbsItem): void {
this._select(this._items.indexOf(item));
setSelection(item: BreadcrumbsItem, payload?: any): void {
this._select(this._items.indexOf(item), payload);
}

private _select(nth: number): void {
private _select(nth: number, payload: any): void {
this._selectedItemIdx = -1;
for (let i = 0; i < this._nodes.length; i++) {
const node = this._nodes[i];
Expand All @@ -228,15 +229,15 @@ export class BreadcrumbsWidget {
dom.addClass(node, 'selected');
}
}
this._onDidSelectItem.fire({ type: 'select', item: this._items[this._selectedItemIdx], node: this._nodes[this._selectedItemIdx] });
this._onDidSelectItem.fire({ type: 'select', item: this._items[this._selectedItemIdx], node: this._nodes[this._selectedItemIdx], payload });
}

setItems(items: BreadcrumbsItem[]): void {
let prefix = commonPrefixLength(this._items, items, (a, b) => a.equals(b));
let removed = this._items.splice(prefix, this._items.length - prefix, ...items.slice(prefix));
this._render(prefix);
dispose(removed);
this._focus(-1);
this._focus(-1, undefined);
}

private _render(start: number): void {
Expand Down Expand Up @@ -275,8 +276,8 @@ export class BreadcrumbsWidget {
for (let el = event.target; el; el = el.parentElement) {
let idx = this._nodes.indexOf(el as any);
if (idx >= 0) {
this._focus(idx);
this._select(idx);
this._focus(idx, event);
this._select(idx, event);
break;
}
}
Expand Down
77 changes: 53 additions & 24 deletions src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import { IEditorGroupsService } from 'vs/workbench/services/group/common/editorG
import { IBreadcrumbsService } from 'vs/workbench/browser/parts/editor/breadcrumbs';
import { symbolKindToCssClass } from 'vs/editor/common/modes';
import { BreadcrumbsPicker, BreadcrumbsFilePicker, BreadcrumbsOutlinePicker } from 'vs/workbench/browser/parts/editor/breadcrumbsPicker';
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';

class Item extends BreadcrumbsItem {

Expand Down Expand Up @@ -113,6 +114,9 @@ export class BreadcrumbsControl {

static HEIGHT = 25;

static readonly Payload_Reveal = {};
static readonly Payload_Pick = {};

static CK_BreadcrumbsVisible = new RawContextKey('breadcrumbsVisible', false);
static CK_BreadcrumbsActive = new RawContextKey('breadcrumbsActive', false);

Expand Down Expand Up @@ -223,39 +227,29 @@ export class BreadcrumbsControl {
}

this._editorGroup.focus();
const { element } = event.item as Item;

if (this._shouldRevealItem(event)) {
// reveal the item
this._widget.setSelection(undefined);
this._revealInEditor(element);
return;
}

// show picker
this._contextViewService.showContextView({
getAnchor() {
return event.node;
},
render: (parent: HTMLElement) => {
let { element } = event.item as Item;
let ctor: IConstructorSignature2<HTMLElement, BreadcrumbElement, BreadcrumbsPicker> = element instanceof FileElement ? BreadcrumbsFilePicker : BreadcrumbsOutlinePicker;
let res = this._instantiationService.createInstance(ctor, parent, element);
res.layout({ width: 220, height: 330 });
let listener = res.onDidPickElement(data => {
this._contextViewService.hideContextView();
this._widget.setSelection(undefined);
if (!data) {
return;
}
if (URI.isUri(data)) {
// open new editor
this._editorService.openEditor({ resource: data });

} else if (data instanceof OutlineElement) {

let resource: URI;
let candidate = data.parent;
while (candidate) {
if (candidate instanceof OutlineModel) {
resource = candidate.textModel.uri;
break;
}
candidate = candidate.parent;
}

this._editorService.openEditor({ resource, options: { selection: Range.collapseToStart(data.symbol.selectionRange) } });

if (data) {
this._revealInEditor(data);
}
});
this._breadcrumbsPickerShowing = true;
Expand All @@ -274,6 +268,28 @@ export class BreadcrumbsControl {
const value = this._widget.isDOMFocused() || this._breadcrumbsPickerShowing;
this._ckBreadcrumbsActive.set(value);
}

private _revealInEditor(data: any): void {
if (URI.isUri(data)) {
// open new editor
this._editorService.openEditor({ resource: data });
} else if (data instanceof FileElement) {
//
this._editorService.openEditor({ resource: data.uri });

} else if (data instanceof OutlineElement) {
//
let model = OutlineModel.get(data);
this._editorService.openEditor({
resource: model.textModel.uri,
options: { selection: Range.collapseToStart(data.symbol.selectionRange) }
});
}
}

private _shouldRevealItem({ payload }: IBreadcrumbsItemEvent): boolean {
return payload === BreadcrumbsControl.Payload_Reveal || (payload instanceof StandardMouseEvent && payload.metaKey);
}
}

//#region commands
Expand Down Expand Up @@ -318,13 +334,26 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({
id: 'breadcrumbs.selectFocused',
weight: KeybindingsRegistry.WEIGHT.workbenchContrib(),
primary: KeyCode.Enter,
secondary: [KeyCode.DownArrow, KeyCode.Space],
secondary: [KeyCode.DownArrow],
when: ContextKeyExpr.and(BreadcrumbsControl.CK_BreadcrumbsVisible, BreadcrumbsControl.CK_BreadcrumbsActive),
handler(accessor) {
const groups = accessor.get(IEditorGroupsService);
const breadcrumbs = accessor.get(IBreadcrumbsService);
const widget = breadcrumbs.getWidget(groups.activeGroup.id);
widget.setSelection(widget.getFocused(), BreadcrumbsControl.Payload_Pick);
}
});
KeybindingsRegistry.registerCommandAndKeybindingRule({
id: 'breadcrumbs.revealFocused',
weight: KeybindingsRegistry.WEIGHT.workbenchContrib(),
primary: KeyMod.Shift | KeyCode.Enter,
secondary: [KeyCode.Space],
when: ContextKeyExpr.and(BreadcrumbsControl.CK_BreadcrumbsVisible, BreadcrumbsControl.CK_BreadcrumbsActive),
handler(accessor) {
const groups = accessor.get(IEditorGroupsService);
const breadcrumbs = accessor.get(IBreadcrumbsService);
const widget = breadcrumbs.getWidget(groups.activeGroup.id);
widget.setSelection(widget.getFocused());
widget.setSelection(widget.getFocused(), BreadcrumbsControl.Payload_Reveal);
}
});
KeybindingsRegistry.registerCommandAndKeybindingRule({
Expand Down

0 comments on commit d1f47a1

Please sign in to comment.