diff --git a/src/vs/workbench/browser/parts/statusbar/statusbarActions.ts b/src/vs/workbench/browser/parts/statusbar/statusbarActions.ts index 4f1772e91c0..e5ade225105 100644 --- a/src/vs/workbench/browser/parts/statusbar/statusbarActions.ts +++ b/src/vs/workbench/browser/parts/statusbar/statusbarActions.ts @@ -3,7 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import 'vs/css!./media/statusbarpart'; import { localize } from 'vs/nls'; import { IStatusbarService } from 'vs/workbench/services/statusbar/browser/statusbar'; import { Action } from 'vs/base/common/actions'; @@ -17,6 +16,8 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic import { StatusbarViewModel } from 'vs/workbench/browser/parts/statusbar/statusbarModel'; import { RawContextKey } from 'vs/platform/contextkey/common/contextkey'; +export const CONTEXT_STATUS_BAR_FOCUSED = new RawContextKey('statusBarFocused', false, localize('statusBarFocused', "Whether the status bar has keyboard focus")); + export class ToggleStatusbarEntryVisibilityAction extends Action { constructor(id: string, label: string, private model: StatusbarViewModel) { @@ -45,8 +46,6 @@ export class HideStatusbarEntryAction extends Action { } } -export const CONTEXT_STATUS_BAR_FOCUSED = new RawContextKey('statusBarFocused', false, localize('statusBarFocused', "Whether the status bar has keyboard focus")); - KeybindingsRegistry.registerCommandAndKeybindingRule({ id: 'workbench.statusBar.focusPrevious', weight: KeybindingWeight.WorkbenchContrib, diff --git a/src/vs/workbench/browser/parts/statusbar/statusbarItem.ts b/src/vs/workbench/browser/parts/statusbar/statusbarItem.ts index a828de3be1d..a770515f9fa 100644 --- a/src/vs/workbench/browser/parts/statusbar/statusbarItem.ts +++ b/src/vs/workbench/browser/parts/statusbar/statusbarItem.ts @@ -3,7 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import 'vs/css!./media/statusbarpart'; import { toErrorMessage } from 'vs/base/common/errorMessage'; import { Disposable, MutableDisposable } from 'vs/base/common/lifecycle'; import { SimpleIconLabel } from 'vs/base/browser/ui/iconLabel/simpleIconLabel'; diff --git a/src/vs/workbench/browser/parts/statusbar/statusbarModel.ts b/src/vs/workbench/browser/parts/statusbar/statusbarModel.ts index 65e6cfca2fd..e10ac19519e 100644 --- a/src/vs/workbench/browser/parts/statusbar/statusbarModel.ts +++ b/src/vs/workbench/browser/parts/statusbar/statusbarModel.ts @@ -9,7 +9,7 @@ import { hide, show, isAncestor } from 'vs/base/browser/dom'; import { IStorageService, StorageScope, IStorageValueChangeEvent, StorageTarget } from 'vs/platform/storage/common/storage'; import { Emitter } from 'vs/base/common/event'; -interface IStatusbarEntryPriority { +export interface IStatusbarEntryPriority { /** * The main priority of the entry that @@ -40,7 +40,7 @@ export interface IStatusbarViewModelEntry { export class StatusbarViewModel extends Disposable { - static readonly HIDDEN_ENTRIES_KEY = 'workbench.statusbar.hidden'; + private static readonly HIDDEN_ENTRIES_KEY = 'workbench.statusbar.hidden'; private readonly _onDidChangeEntryVisibility = this._register(new Emitter<{ id: string, visible: boolean }>()); readonly onDidChangeEntryVisibility = this._onDidChangeEntryVisibility.event; @@ -186,9 +186,11 @@ export class StatusbarViewModel extends Disposable { } isEntryFocused(): boolean { - const focused = this._entries.find(entry => isAncestor(document.activeElement, entry.container)); + return !!this.getFocusedEntry(); + } - return !!focused; + private getFocusedEntry(): IStatusbarViewModelEntry | undefined { + return this._entries.find(entry => isAncestor(document.activeElement, entry.container)); } private focusEntry(delta: number, restartPosition: number): void { @@ -204,7 +206,7 @@ export class StatusbarViewModel extends Disposable { return entry; }; - const focused = this._entries.find(entry => isAncestor(document.activeElement, entry.container)); + const focused = this.getFocusedEntry(); if (focused) { const entry = getVisibleEntry(this._entries.indexOf(focused) + delta); if (entry) { diff --git a/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts b/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts index ca47b7241b6..b096a79a384 100644 --- a/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts +++ b/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts @@ -31,29 +31,9 @@ import { IHoverService } from 'vs/workbench/services/hover/browser/hover'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IHoverDelegate, IHoverDelegateOptions } from 'vs/base/browser/ui/iconLabel/iconHoverDelegate'; import { CONTEXT_STATUS_BAR_FOCUSED, HideStatusbarEntryAction, ToggleStatusbarEntryVisibilityAction } from 'vs/workbench/browser/parts/statusbar/statusbarActions'; -import { IStatusbarViewModelEntry, StatusbarViewModel } from 'vs/workbench/browser/parts/statusbar/statusbarModel'; +import { IStatusbarEntryPriority, IStatusbarViewModelEntry, StatusbarViewModel } from 'vs/workbench/browser/parts/statusbar/statusbarModel'; import { StatusbarEntryItem } from 'vs/workbench/browser/parts/statusbar/statusbarItem'; -interface IStatusbarEntryPriority { - - /** - * The main priority of the entry that - * defines the order of appearance. - * - * May not be unique across all entries. - */ - readonly primary: number; - - /** - * The secondary priority of the entry - * is used in case the main priority - * matches another one's priority. - * - * Should be unique across all entries. - */ - readonly secondary: number; -} - interface IPendingStatusbarEntry { readonly id: string; readonly alignment: StatusbarAlignment; @@ -160,9 +140,6 @@ export class StatusbarPart extends Part implements IStatusbarService { const itemContainer = this.doCreateStatusItem(id, alignment, ...coalesce([entry.showBeak ? 'has-beak' : undefined])); const item = this.instantiationService.createInstance(StatusbarEntryItem, itemContainer, entry, this.hoverDelegate); - // Append to parent - this.appendOneStatusbarEntry(itemContainer, alignment, priority); - // Add to view model const viewModelEntry: IStatusbarViewModelEntry = new class implements IStatusbarViewModelEntry { readonly id = id; @@ -175,6 +152,9 @@ export class StatusbarPart extends Part implements IStatusbarService { }; const viewModelEntryDispose = this.viewModel.add(viewModelEntry); + // Append to parent + this.appendOneStatusbarEntry(viewModelEntry); + return { update: entry => { item.update(entry); @@ -276,43 +256,20 @@ export class StatusbarPart extends Part implements IStatusbarService { } } - private appendOneStatusbarEntry(itemContainer: HTMLElement, alignment: StatusbarAlignment, priority: IStatusbarEntryPriority): void { - const entries = this.viewModel.getEntries(alignment); + private appendOneStatusbarEntry(entry: IStatusbarViewModelEntry): void { + const entries = this.viewModel.getEntries(entry.alignment); - if (alignment === StatusbarAlignment.RIGHT) { + if (entry.alignment === StatusbarAlignment.RIGHT) { entries.reverse(); // reversing due to flex: row-reverse } - const target = assertIsDefined(alignment === StatusbarAlignment.LEFT ? this.leftItemsContainer : this.rightItemsContainer); + const target = assertIsDefined(entry.alignment === StatusbarAlignment.LEFT ? this.leftItemsContainer : this.rightItemsContainer); - // find an entry that has lower priority than the new one - // and then insert the item before that one - let appended = false; - for (const entry of entries) { - - // pick a priority that ideally is not the same - // by falling back to secondary priority - let existingEntryPriority = entry.priority.primary; - let newEntryPriority = priority.primary; - if (existingEntryPriority === newEntryPriority) { - existingEntryPriority = entry.priority.secondary; - newEntryPriority = priority.secondary; - } - - // insert according to priority - if ( - alignment === StatusbarAlignment.LEFT && existingEntryPriority < newEntryPriority || - alignment === StatusbarAlignment.RIGHT && existingEntryPriority > newEntryPriority // reversing due to flex: row-reverse - ) { - target.insertBefore(itemContainer, entry.container); - appended = true; - break; - } - } - - // Fallback to just appending otherwise - if (!appended) { - target.appendChild(itemContainer); + const index = entries.indexOf(entry); + if (index + 1 === entries.length) { + target.appendChild(entry.container); // append at the end if last + } else { + target.insertBefore(entry.container, entries[index + 1].container); // insert before next element otherwise } }